UIButton does not work when it in UIScrollView

My structure of views:


The problem is UIButton doesn’t work when I touch it.
I create it with code:

  • Why is UIScrollView leaving space on top and does not scroll to the bottom
  • Keeping the contentOffset in a UICollectionView while rotating Interface Orientation
  • UIImageView does not zoom
  • UIScrollView and cancel a zooming pinch gesture
  • Make UICollectionView scroll right to left?
  • (Swift) NSTimer Stop when Scrolling
  • btn = [[UIButton alloc] init];
    [btn setImage:image forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(tileTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
    btn.layer.zPosition = 1;
    [self addSubview:btn];

    I’ve also add this:

    scroll.delaysContentTouches = NO;
    scroll.canCancelContentTouches = NO;

    But my button doesn’t work anyway. I can’t cancelContentTouches or set delay for UITableView because if I set it, UITableView stop scrolling verticaly.

    Thanks for any help!

    7 Solutions Collect From Internet About “UIButton does not work when it in UIScrollView”

    Create a subclass of UIScrollview with

    - (BOOL)touchesShouldCancelInContentView:(UIView *)view {
      return NO;

    If you are not getting that message, set:

    scrollView.delaysContentTouches = NO;

    The problem is because of the way touchesShouldCancelInContentView behaves by default, it returns NO only if the subview is an UIControl, but your button is hidden inside the CustomView which isn’t.

    Came across the same scenario. UIScrollView in separate class and adding button through a custom view. ‘NSNotificationCenter’ helped me solving the issue.
    Sample code:

        NSDictionary *dict=[NSDictionary dictionaryWithObject:@"index" forKey:@"index"];
        [[NSNotificationCenter defaultCenter]postNotificationName:@"Action" object:nil userInfo:dict];

    In the class containing Scroll View:

    - (void)viewDidLoad
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doAction:) name:@"Action" object:nil];
    -(void)doAction:(NSNotification *) notification
        NSString* value =[notification.userInfo valueForKey:@"index"];
        // .......

    Enable userInteraction for scroll view, custom view and button.

    I guess you need to set the button frame. By default if you use btn = [[UIButton alloc] init]; method to initialize button it will be UIButtonTypeCustom. Also set a background color to it for debugging purpose to note down where the button is actually placed.
    Now for your case you need to set the frame for that button like btn.frame = CGRectMake(0,0,100,100);

    For the inner UIScrollView implement this delegate method.

    - (BOOL)touchesShouldCancelInContentView:(UIView *)view
           return ![view isKindOfClass:[UIButton class]];

    This may work.

    Your CustomView’s frame could be interfering with your UIButton. Are they overlapping? Add your button to the CustomView just to test by [CustomView addSubview:UIButton]; (using your values of course). If it works, then your issue is most likely an overlap.

    Link from Capt.Hook helped me. I used UIGestureRecognizer instead of UIButtons.

    Allow UIScrollView and its subviews to both respond to a touch
    Use it, if you have the similar problem.

    Add all subviews from CustomView to ScrollView. And hide the CustomView. Make sure CustomView(ContainerView of scrollView) should also be a subView of scrollView.

    I had same issue & same hierarchy of the views, With latest sdk , just use it :

    Setting delaysContentTouches to NO for UIButton in the same UITableViewCell.

    self.tableView.delaysContentTouches = NO