0

我正在开发杂志查看器,由于 html5 交互式内容,我必须将 UIWebView 用于页面。首先,我在 UIScrollView 中尝试了 uiwebviews,但滚动视图在滑动页面上太慢了。所以现在我正在尝试编写自己的类似滚动视图的代码。我有一个 MainView.xib、一个视图控制器 (Viewer) 和扩展 UIWindow 类 (TouchCapturingWindow),我从这里获取:http ://wyldco.com/blog/2010/11/how-to-capture-touches-over- a-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

查看器.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

查看器.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)

}

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

于 2012-08-14T15:34:02.977 回答