0

私は雑誌ビューアーに取り組んでおり、html5 のインタラクティブなコンテンツのため、ページに UIWebView を使用する必要があります。最初に UIScrollView で uiwebviews を試しましたが、ページをスライドさせるとスクロールビューが遅すぎました。だから今、私は自分のスクロールビューのようなコードを書こうとしています。MainView.xib、ビュー コントローラー (Viewer)、および拡張された UIWindow クラス (TouchCapturingWindow) をここから取得します。 a-uiwebview/

ページを速くスライドさせようとすると問題ありませんが、タッチして指を引っ張らずにゆっくりスライドすると、View Controller がタッチ イベントを受信しなくなり、ページが動かなくなります。TouchCapturingWindow をログに記録していますが、まだイベントを送信しています。多くの情報やチュートリアルを検索しましたが、うまくいきませんでした。タッチイベントを継続的に受信するにはどうすればよいですか?

プロジェクトのこの部分のみを含む単純な Xcode プロジェクトをアップロードしました。ここからダウンロードできます : http://testdergi.mysys.com/touchEvents.zip プロジェクトを実行するときは、まず [ページのダウンロード] ボタンをタップしてページ (180Kb) をダウンロードし、次に [ビューアーを開く] ボタンをタップします。

以下のコードを確認することもできます。

TouchCapturingWindow.h :

@interface TouchCapturingWindow : UIWindow {
    NSMutableArray *views;

@private
    UIView *touchView;
}

- (void)addViewForTouchPriority:(UIView*)view;
- (void)removeViewForTouchPriority:(UIView*)view;

@end

TouchCapturingWindow.m :

@implementation TouchCapturingWindow


- (void)dealloc {

}

- (void)addViewForTouchPriority:(UIView*)view {
    if ( !views ) views = [[NSMutableArray alloc] init];
    [views addObject:view];
}

- (void)removeViewForTouchPriority:(UIView*)view {
    if ( !views ) return;
    [views removeObject:view];
}

- (void)sendEvent:(UIEvent *)event {

    //get a touch
    UITouch *touch = [[event allTouches] anyObject];

    //check which phase the touch is at, and process it
    if (touch.phase == UITouchPhaseBegan) {
            for ( UIView *view in views ) {
                //if ( CGRectContainsPoint([view frame], [touch locationInView:[view superview]]) ) {
                NSLog(@"TouchCapturingWindow --> TouchPhaseBegan");
                touchView = view;
                [touchView touchesBegan:[event allTouches] withEvent:event];
                break;
            }
    }
    else if (touch.phase == UITouchPhaseMoved) {
            NSLog(@"TouchCapturingWindow --> TouchPhaseMoved");

            if ( touchView ) {

                [touchView touchesMoved:[event allTouches] withEvent:event];
            }
            else
            {
                NSLog(@"touch view is nil");
            }

    }
    else if (touch.phase == UITouchPhaseCancelled) {
            NSLog(@"TouchCapturingWindow --> TouchPhaseCancelled");
            if ( touchView ) {
                [touchView touchesCancelled:[event allTouches] withEvent:event];
                touchView = nil;
            }
    }
    else if (touch.phase == UITouchPhaseEnded) {
            NSLog(@"TouchCapturingWindow --> TouchPhaseEnded");
            if ( touchView ) {
                [touchView touchesEnded:[event allTouches] withEvent:event];
                touchView = nil;
            }
    }

    //we need to send the message to the super for the
    //text overlay to work (holding touch to show copy/paste)
    [super sendEvent:event];
}

@end

Viewer.h :

@interface Viewer : UIViewController{
    int currentPage;
    int totalPages;
    IBOutlet UIView *pagesView;
    int lastTchX;
    int difference;
    BOOL hasMoved;
    int touchBeganSeritX;
}

- (IBAction)backBtnClicked:(id)sender;
- (void)loadImages;
- (void)animationDidStop;
- (void)loadSinglePage:(int)pageNo;

@property (nonatomic, retain) IBOutlet UIView *pagesView;

@end

Viewer.m :

@interface Viewer ()

@end

@implementation Viewer

@synthesize pagesView;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (IBAction)backBtnClicked:(id)sender
{
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)loadImages
{
    for(UIView *subView in pagesView.subviews)
    {
        [subView removeFromSuperview];
    }

    currentPage = 1;
    totalPages = 12;
    for(int count = 1; count <= 12; count++)
    {
        [self loadSinglePage:count];
    }

}

- (void)loadSinglePage:(int)pageNo
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory , NSUserDomainMask, YES);
    NSString *cachesDir = [paths objectAtIndex:0];
    NSString *pagesDir = [NSString stringWithFormat:@"%@/pages", cachesDir];

    int pageX = (pageNo - 1) * 768;

    UIWebView *aPageWebView = [[UIWebView alloc] init];
    [aPageWebView setFrame:CGRectMake(pageX, 0, 768, 1024)];
    aPageWebView.backgroundColor = [UIColor clearColor];
    aPageWebView.opaque = YES;
    [aPageWebView setClearsContextBeforeDrawing:YES];
    aPageWebView.clipsToBounds = NO;
    [aPageWebView setScalesPageToFit:YES];

    NSString *hamData = [NSString stringWithFormat:@"<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"user-scalable=yes, width=1024, height=1365, maximum-scale=1.0\"><style type=\"text/css\">body {margin:0; padding:0;}</style></head><body bgcolor=\"#508CCF\"><div id=\"touchable\" style=\"top:0px; left:0px; width:1024px; height:1365px; background-image:url(%@.jpg)\"></div></body></html>", [[NSNumber numberWithInt:pageNo] stringValue]];

    [aPageWebView loadHTMLString:hamData baseURL:[NSURL fileURLWithPath:pagesDir isDirectory:YES]];
    aPageWebView.scrollView.bounces = NO;
    [aPageWebView.scrollView setMaximumZoomScale:1.3333f];
    [aPageWebView.scrollView setMinimumZoomScale:1.0f];
    aPageWebView.scrollView.zoomScale = 1.0f;
    [aPageWebView setMultipleTouchEnabled:YES];
    [pagesView addSubview:aPageWebView];
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchesBegan");

    UITouch *myTouch = [[event allTouches] anyObject];
    int curTchX = [myTouch locationInView:self.view].x;

    lastTchX = curTchX;
    hasMoved = NO;

    touchBeganSeritX = pagesView.frame.origin.x;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Viewer : .....moved");

    hasMoved = YES;
    UITouch *myTouch = [[event allTouches] anyObject];
    int curTchX = [myTouch locationInView:self.view].x;
    difference = curTchX - lastTchX;

    int newX = (pagesView.frame.origin.x + difference);
    if(newX <= 0)
    {
        [pagesView setFrame:CGRectMake((pagesView.frame.origin.x + difference), 0, pagesView.frame.size.width, 1024)];
    }
    lastTchX = curTchX;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchesEnded");
    if(hasMoved == YES)
    {
        hasMoved = NO;

        int curSeritX = pagesView.frame.origin.x;
        curSeritX = curSeritX / (-1);

        int newX = 0;

        if(difference < 0) //Sağa geçilecek
        {
            if((currentPage + 1) <= totalPages)
            {
                currentPage++;
            }
        }
        else //Sola geçilecek
        {
            if((currentPage - 1) >= 1)
            {
                currentPage--;
            }
        }

        newX = (currentPage - 1)*768*(-1);

        [UIView animateWithDuration:0.2f
                              delay:0.0f
                            options:UIViewAnimationOptionCurveEaseOut
                         animations:^{
                             // Do your animations here.
                             [pagesView setFrame:CGRectMake(newX, 0, pagesView.frame.size.width, pagesView.frame.size.height)];
                         }
                         completion:^(BOOL finished){
                             if (finished) {
                                 // Do your method here after your animation.
                             }
                         }];
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchesCancelled");
}


- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end
4

1 に答える 1

0

私は自分の質問に答えています。苦労の末、見つけたもの。「(void)sendEvent:(UIEvent *)event」メソッドを以下のコードのように変更しました。「[super sendEvent:event];」の使用を見ました。UITouchPhaseMoved フェーズの後が問題です。

- (void)sendEvent:(UIEvent *)event {
    //we need to send the message to the super for the
    //text overlay to work (holding touch to show copy/paste)
    //[super sendEvent:event];

    //get a touch
    UITouch *touch = [[event allTouches] anyObject];

    //check which phase the touch is at, and process it
    if (touch.phase == UITouchPhaseBegan) {
            for ( UIView *view in views ) {
                //if ( CGRectContainsPoint([view frame], [touch locationInView:[view superview]]) ) {
                NSLog(@"TouchCapturingWindow --> TouchPhaseBegan");
                touchView = view;
                [touchView touchesBegan:[event allTouches] withEvent:event];


                break;
            }
        [super sendEvent:event];
    }
    else if (touch.phase == UITouchPhaseMoved) {
            NSLog(@"TouchCapturingWindow --> TouchPhaseMoved");

            if ( touchView ) {

                [touchView touchesMoved:[event allTouches] withEvent:event];

                int curTchX = [touch locationInView:self].x;
                NSLog(@"curTchX : %d", curTchX);
            }
            else
            {
                NSLog(@"touch view is nil");
            }

    }
    else if (touch.phase == UITouchPhaseCancelled) {
            NSLog(@"TouchCapturingWindow --> TouchPhaseCancelled");
            if ( touchView ) {
                [touchView touchesCancelled:[event allTouches] withEvent:event];
                touchView = nil;
            }
        [super sendEvent:event];
    }
    else if (touch.phase == UITouchPhaseEnded) {
            NSLog(@"TouchCapturingWindow --> TouchPhaseEnded");
            if ( touchView ) {
                [touchView touchesEnded:[event allTouches] withEvent:event];
                touchView = nil;
            }
        [super sendEvent:event];
    }

    //we need to send the message to the super for the
    //text overlay to work (holding touch to show copy/paste)

}

しかし、新しい問題は次のとおりです。Web ページにビデオを追加し、スライダーでビデオを転送しようとすると、ページが移動します。ユーザーがビデオをタップしたかどうかを検出する方法を見つける必要があります。

于 2012-08-14T15:34:02.977 に答える