Swipe html pagesLoad another html page if I swipe

2019-09-03 04:15发布

问题:

How would it be possible to swipe (left) html pages?

回答1:

Handling gestures happening on a web view is tricky, since UIWebView is really greedy with touches and wants to handle them all.

As usual with web views, you could try and do everything with Javascript. You can read something about it in this S.O. post.

The way I prefer handling pinching (zoom) and swiping on a web view though is following:

  1. subclass UIWindow:

       @interface MyWebNavigatorWindow : UIWindow {
    
  2. install an instance of that window type as the window for your app in application:didFinishLaunchingWithOptions:

      _window = [[MyWebNavigatorWindow alloc] initWithFrame:rect];
    

    Alternatively, you can assign a class to your window object in Interface Builder.

  3. handle swipes and pinches in sendEvent in your MyWebNavigatorWindow class:

      - (void)sendEvent:(UIEvent*)event {
        NSSet* allTouches = [event allTouches];
        UITouch* touch = [allTouches anyObject];
        UIView* touchView = [touch view];
    
  4. You will need a mechanism in sendEvent to detect when the touch happens inside of your web view. In my case, I "register" all the views that I want to handle touch for and then check if the touch is inside them:

            for (UIView* view in self.controlledViews) {  // self.controlledViews is the array of all "registered" views
          if ([touchView isDescendantOfView:view]) {
    
  5. then I handle the various touch phases to detect what kind of gesture it is (code snippet not compilable, but it gives the idea):

            if (touch.phase == UITouchPhaseBegan) {
            NSLog(@"TOUCH BEGAN");
            _initialView = touchView;
            startTouchPosition1 = [touch locationInView:self];
            startTouchTime = touch.timestamp;
    
            if ([allTouches count] > 1) {
                startTouchPosition2 = [[[allTouches allObjects] objectAtIndex:1] locationInView:self];
                previousTouchPosition1 = startTouchPosition1;
                previousTouchPosition2 = startTouchPosition2;
            }
        }
    
        if (touch.phase == UITouchPhaseMoved) {
            NSLog(@"TOUCH MOVED");
            if ([allTouches count] > 1) {
                CGPoint currentTouchPosition1 = [[[allTouches allObjects] objectAtIndex:0] locationInView:self];
                CGPoint currentTouchPosition2 = [[[allTouches allObjects] objectAtIndex:1] locationInView:self];
    
                CGFloat currentFingerDistance = CGPointDist(currentTouchPosition1, currentTouchPosition2);
                CGFloat previousFingerDistance = CGPointDist(previousTouchPosition1, previousTouchPosition2);
                if (fabs(currentFingerDistance - previousFingerDistance) > ZOOM_DRAG_MIN) {
                    NSNumber* movedDistance = [NSNumber numberWithFloat:currentFingerDistance - previousFingerDistance];
                    if (currentFingerDistance > previousFingerDistance) {
                        NSLog(@"zoom in");
                        [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_ZOOM_IN object:movedDistance];
                    } else {
                        NSLog(@"zoom out");
                        [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_ZOOM_OUT object:movedDistance];
                    }
                }
            }
        }
    
        if (touch.phase == UITouchPhaseEnded) {
            CGPoint currentTouchPosition = [touch locationInView:self];
    
            // Check if it's a swipe
            if (fabsf(startTouchPosition1.x - currentTouchPosition.x) >= SWIPE_DRAG_HORIZ_MIN &&
                fabsf(startTouchPosition1.x - currentTouchPosition.x) > fabsf(startTouchPosition1.y - currentTouchPosition.y) &&
                touch.timestamp - startTouchTime < 0.7
                ) {
                // It appears to be a swipe.
                if (startTouchPosition1.x < currentTouchPosition.x) {
                    NSLog(@"swipe right");
                    [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_SWIPE_RIGHT object:touch];
                } else {
                    NSLog(@"swipe left");
                    [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_SWIPE_LEFT object:touch];
                }
            }
            startTouchPosition1 = CGPointMake(-1, -1);
            _initialView = nil;
        }