Search code examples
iosuiviewuiswipegesturerecognizer

iOS, UISwipeGestureRecognizer on Custom UIView - not working


I am unable to have a successful UISwipeGestureRecognizer set onto my custom view. I have tested on the main self.view with success, but i cannot get it to work on my custom.

Parent.m

@property (strong, nonatomic) UISummaryChartView *chartView;

...

- (void)viewDidLoad {
    [super viewDidLoad];
    self.chartView = [[UISummaryChartView alloc] initWithWidth:self.view.frame.size.width andHeight:self.view.frame.size.height withView:self.view];
    [self.chartView openBox];

    UISwipeGestureRecognizer *swipeGest = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeDetected:)];
    [swipeGest setDirection:(UISwipeGestureRecognizerDirectionUp)];

    [self.view addGestureRecognizer:swipeGest];
}

-(void)swipeDetected: (UISwipeGestureRecognizer *) sender{
    NSLog(@"swiped..");
    if(self.chartView.frame.size.height > 50){
        //chart view is open
        NSLog(@"closing");
        [self.chartView closeBox];
    }
}

UISummaryChartView.h

UISummaryChartView : UIView

-(id) initWithWidth:(CGFloat)inWidth andHeight:(CGFloat)inHeight withView: (UIView*) theView{
    self = [super init];

    self.mainView = theView;
    //super view bounds
    self.viewWidth = inWidth;
    self.viewHeight = inHeight;
    CGFloat startx = 2;
    CGFloat starty = 0;
    self.width = self.viewWidth - 10;
    self.height = (self.viewHeight / 100) * 50;
    self.view1Frame = CGRectMake(startx, starty, self.width, self.height);

    return self;
}

-(void) openBox{
    CGRect startFrame = CGRectMake(0, 10, self.mainView.frame.size.width, 1);
    self.view1 = [[UIView alloc] initWithFrame:startFrame];
    [self.mainView addSubview:self.view1];
    [UIView animateWithDuration:0.5 animations:^(void){
        [self.view1 setBackgroundColor:[UIColor colorWithRed:(float)126/255.0 green:(float)35/255.0 blue:(float)32/255.0 alpha:1]];
        self.view1.frame = self.view1Frame;
    } completion:^(BOOL finished){

    }];
}

Solution

  • You have 2 things to do to make this work:

    First, your UIView subclass has no frame or bounds because you used init and not initWithFrame:

    Second, you have to set a delegate on your main UIViewController and implement the - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch method. This works:

    in UISummaryCharView.m

    #import "UISummaryChartView.h"
    
    @implementation UISummaryChartView
    
    @synthesize mainView;
    
    -(id) initWithWidth:(CGFloat)inWidth andHeight:(CGFloat)inHeight withView: (UIView*) theView{
        self = [super initWithFrame:theView.frame]; // THIS IS IMPORTANT
        self.mainView = theView;
        //super view bounds
        self.viewWidth = inWidth;
        self.viewHeight = inHeight;
        CGFloat startx = 2;
        CGFloat starty = 0;
        self.width = self.viewWidth - 10;
        self.height = (self.viewHeight / 100) * 50;
        self.view1Frame = CGRectMake(startx, starty, self.width, self.height);
        NSLog(@"frame %@",NSStringFromCGRect(self.frame));
        NSLog(@"bounds %@",NSStringFromCGRect(self.bounds));
        return self;
    }
    
    -(void) openBox{
    
        CGRect startFrame = CGRectMake(0, 10, self.mainView.frame.size.width, 1);
        self.view1 = [[UIView alloc] initWithFrame:startFrame];
        [self.mainView addSubview:self.view1];
        [UIView animateWithDuration:0.5 animations:^(void){
            [self.view1 setBackgroundColor:[UIColor colorWithRed:(float)126/255.0 green:(float)35/255.0 blue:(float)32/255.0 alpha:1]];
            self.view1.frame = self.view1Frame;
        } completion:^(BOOL finished){
            NSLog(@"frame %@",NSStringFromCGRect(self.frame));
            NSLog(@"bounds %@",NSStringFromCGRect(self.bounds));
        }];
    }
    
    
    -(void)closeBox{
        NSLog(@"close box");
        // your closeBox method
    }
    
    @end
    

    in Parent.m

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    
        self.chartView = [[UISummaryChartView alloc] initWithWidth:self.view.frame.size.width andHeight:self.view.frame.size.height withView:self.view];
        [self.chartView openBox];
    
        UISwipeGestureRecognizer *swipeGest = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeDetected:)];
        [swipeGest setDirection:(UISwipeGestureRecognizerDirectionUp)];
    
        [[self view] addSubview:self.chartView];
    
        self.chartView.userInteractionEnabled = YES;
        [self.chartView addGestureRecognizer:swipeGest];
        swipeGest.delegate = self;
    
    
    }
    
    -(void)swipeDetected: (UISwipeGestureRecognizer *) sender{
        NSLog(@"swiped..");
        if(self.chartView.frame.size.height > 50){
            //chart view is open
            NSLog(@"closing");
            [self.chartView closeBox];
        }
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    {
        NSLog(@"shouldReceiveTouch?");
        return YES;
    }