Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIButton not responding after set frame within UIScrollview

I have a UIScrollView which content is designed with Interface Builder. It has a table with a UIButton below. If the button wasn't moved before, it works (touchesBegan and TouchUpInside get called), but if it was moved using 'button.frame = ' in response of content growth (the table got bigger), it stops responding to any touch.

I verified that there's no hidden view in front of it, I even used bringViewToFront.

like image 361
Johnny Everson Avatar asked May 24 '11 11:05

Johnny Everson


2 Answers

Check if your UIButton final position is both inside the UITableView and UIScrollView bounds.

It is possible that after you moved it, the UIBUtton is placed outside the bound, and then will not respond to touch events.

One quick set up that can make you verify that is to set the clipToBounds property of your UITableView and UIScrollView to NO, then all content placed outside the bounds will not even be visible.

like image 92
Felipe Sabino Avatar answered Nov 10 '22 20:11

Felipe Sabino


In a project I was working on recently I have a UITableView with a UIButton in the FooterView. When you attempt to scroll past the button, as it is the last item in this UITableView, the button will be pinned to the bottom of the view.

I ran into the same problem as this post when the contents of my UITableView resulted in a contentSize that was less than the height of the UITableView. My UIButton was essentially out of the bounds of the initial frame of the UITableView scrollable content and was thus not receiving any events.

I wanted to post my solution so that anyone else receiving this behavior could be helped.

I had to override pointInside:withEvent and hitTest:withEvent methods within my custom UITableView class:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    BOOL pointInside = [super pointInside:point withEvent:event];

    if (!pointInside) {
        CGRect buttonFrame = [self convertRect:self.myButton.frame  fromView:self];
        if (CGRectContainsPoint(buttonFrame, point)) {
            return YES;
        }
    }

    return pointInside;
}


- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (!self.clipsToBounds && !self.hidden && self.alpha > 0) {
        for (UIView *subview in self.subviews.reverseObjectEnumerator) {
            CGPoint subPoint = [subview convertPoint:point fromView:self];
            UIView *result = [subview hitTest:subPoint withEvent:event];

            if (result != nil) {
                return result;
            }
        }
    }

    // No other subviews have triggered this 'touch' check self.myButton
    CGPoint subPoint = [self.myButton convertPoint:point fromView:self];
    UIView *result = [self.myButton hitTest:subPoint withEvent:event];

    if (result != nil) {
        return result;
    }

    // Pass the 'touch' on if no subviews trigger the 'touch'
    return [super hitTest:point withEvent:event];
}
like image 2
egarlock Avatar answered Nov 10 '22 18:11

egarlock