views:

1190

answers:

2

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 funtions (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.

Thanks so much for the help.

+1  A: 

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.

Don
Check my previous post. Thank you.
intl
Thanks for replying. I figured out the self.view to self, but I'm stuck on the tabBarController part. Could you please elaborate on this?
intl
So the code formats nicely, I'll edit my post.
Don
Thanks for the edit. I'm still having trouble with the tabBarController errors though. I'd really appreciate some help with that, please.Thanks a lot.
intl
Sorry; took me a while to edit it. Look again. Or, look at NSNotification: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSNotification_Class/Reference/Reference.html
Don
Thanks for replying. My tabBarController is set up via IB and I just reference it in the AppDelegate. How would I set up the parent and webView connection then? Also, I understand I have to add the switchToView method in the TabBarController.m, but, I don't have a TabBarController.m, again, due to the creating with IB.
intl
Hmm. You can use the AppDelegate as a type of Singleton, but this would be frowned upon: replace self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0]; with a call to a method you create on your app delegate MainAppDelegate *appDelegate = (MainAppDelegate *) [UIApplication sharedApplication].delegate; [appDelegate switchToTab: 0]; Other than that, you'll have to write your own tab bar controller subclass and do it in code.
Don
A: 

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.

intl