Question

I have viewcontrollers set up to track gestures and commit an action, in this case, change the tab. The code for the viewcontrollers is as follows:

#define HORIZ_SWIPE_DRAG_MIN 100
CGPoint mystartTouchPosition;
BOOL isProcessingListMove;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint newTouchPosition = [touch locationInView:self.view];
    if(mystartTouchPosition.x != newTouchPosition.x || mystartTouchPosition.y != newTouchPosition.y) {
        isProcessingListMove = NO;
    }
    mystartTouchPosition = [touch locationInView:self.view];
    [super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *touch = touches.anyObject;
    CGPoint currentTouchPosition = [touch locationInView:self.view];

    // If the swipe tracks correctly.
    double diffx = mystartTouchPosition.x - currentTouchPosition.x + 0.1; // adding 0.1 to avoid division by zero
    double diffy = mystartTouchPosition.y - currentTouchPosition.y + 0.1; // adding 0.1 to avoid division by zero

    if(abs(diffx / diffy) > 2.5 && abs(diffx) > HORIZ_SWIPE_DRAG_MIN)
    {
        // It appears to be a swipe.
        if(isProcessingListMove) {
            // ignore move, we're currently processing the swipe
            return;
        }

        if (mystartTouchPosition.x < currentTouchPosition.x) {
            isProcessingListMove = YES;
            self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0];
            return;
        }
        else {
            isProcessingListMove = YES;

            self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:2];

            return;
        }
    }
    else if(abs(diffy / diffx) > 1)
    {
        isProcessingListMove = YES;
        [super touchesMoved:touches withEvent:event];
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{
    isProcessingListMove = NO;
    [super touchesEnded:touches withEvent:event];
}

I'd like to have the same gesture do the same thing on a uiwebview I have set up under the view of the viewcontroller. In short, the uiwebview is on the view. When I swipe, I just get the basic uiwebview functions (scrolling). If I set up a custom uiwebview class with the same code as the uiviewcontroller, I get errors. I need to know how to translate that block of code, keeping the functionality intact, to suit the uiwebview.

Was it helpful?

Solution

You should be able to subclass UIWebView and override those methods. You may have to override all of the touch methods, though,

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

EDIT: Ah, I see your errors now. They are because those things don't apply to the UIWebView like they did to the parent (which you already know...)

Since UIWebView is a UIView, you should be able to replace

[touch locationInView:self.view]

with

[touch locationInView:self]

To get to the parent's tab bar controller, though, you'll have to design a different way to do it. You could pass a reference to the parent to your UIWebView subclass and expose a method on the parent for changing which tab is active, for instance:

In your subclass, add a property for the parent tab bar controller:

UITabBarController *parent;

When creating your UIWebView subclass and adding it to the tab bar controller, also set the parent:

webView.parent = self;

If you're setting this up in Interface Builder, make the parent an IBOutlet and hook it up through IB.

In your tab bar controller view, add a method that changes the selected controller. You could use named constants for the view you want to switch to, or methods that describe exactly what you are switching to, but for simplicity, you'd do something conceptually similar this:

- (void) switchToView: (int)viewNumber 
{
    self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:viewNumber]; 
}

then call [parent switchToView:2] in your code.

Another and arguably better way is to use NSNotifications, registering the parent as a listener.

OTHER TIPS

My full code is the following:

#import "CustomWebView.h"

@implementation CustomWebView

//Swipe between tabs
#define HORIZ_SWIPE_DRAG_MIN 100
CGPoint mystartTouchPosition;
BOOL isProcessingListMove;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint newTouchPosition = [touch locationInView:self.view]; "error: request for member 'view' in something not a structure or union"


    if(mystartTouchPosition.x != newTouchPosition.x || mystartTouchPosition.y != newTouchPosition.y) {
        isProcessingListMove = NO;
    }
    mystartTouchPosition = [touch locationInView:self.view]; "error: request for member 'view' in something not a structure or union"
    [super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *touch = touches.anyObject;
    CGPoint currentTouchPosition = [touch locationInView:self.view]; "error: request for member 'view' in something not a structure or union"

    // If the swipe tracks correctly.
    double diffx = mystartTouchPosition.x - currentTouchPosition.x + 0.1; // adding 0.1 to avoid division by zero
    double diffy = mystartTouchPosition.y - currentTouchPosition.y + 0.1; // adding 0.1 to avoid division by zero

    if(abs(diffx / diffy) > 2.5 && abs(diffx) > HORIZ_SWIPE_DRAG_MIN)
    {
        // It appears to be a swipe.
        if(isProcessingListMove) {
            // ignore move, we're currently processing the swipe
            return;
        }

        if (mystartTouchPosition.x < currentTouchPosition.x) {
            isProcessingListMove = YES;
            self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0]; "error: request for member 'tabBarController' in something not a structure or union"
            return;
        }
        else {
            isProcessingListMove = YES;

            self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:2]; "error: request for member 'tabBarController' in something not a structure or union"

            return;
        }
    }
    else if(abs(diffy / diffx) > 1)
    {
        isProcessingListMove = YES;
        [super touchesMoved:touches withEvent:event];
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{
    isProcessingListMove = NO;
    [super touchesEnded:touches withEvent:event];
}
// End of swipe

@end

The errors are as follows are included with the code.

I appreciate the help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top