2012-08-13 103 views
0

我正在处理杂志查看器,并且因为html5交互式内容而必须使用UIWebView作为页面。首先,我尝试在UIScrollView中使用uiwebviews,但滑动页面上的滚动视图太慢。 所以现在我正在尝试编写自己的类似scrollview的代码。我有一个MainView.xib,一个视图控制器(查看器)和扩展UIWindow类(TouchCapturingWindow),我从这里取:http://wyldco.com/blog/2010/11/how-to-capture-touches-over-a-uiwebview/UIViewController停止接收UIWebView上的触摸事件

当我尝试快速滑动页面时,没有任何问题,但是当我触摸并缓慢滑动通过不拉我的手指,“观看者”视图控制器停止接收触摸事件,因此页面停止移动。我正在记录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 

回答

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) 

} 

但新问题是;如果我在网页中添加视频并尝试使用其滑块转发视频,则页面正在移动。我必须找到一种方法来检测用户是否点击视频。