2
votes

I have some UIButtons inside a UIScrollView. When the view first loads there are about 8 buttons showing in the UIScrollView, all these buttons are visible and clickable.

However, once I scroll, any button that wasn't there when the view initially loaded isn't clickable.

Given I have a function that creates every button programatically on view load, is it possible that the addTarget function isn't working? I create about 280 buttons at the start and add the UITouchUpInside event programatically.

--Edit--

This is more or less the code, called inside viewDidLoad function

for (int i = 0; i < numberOfButtons; i++){
    //Display stuff here
    MyButton *aButton = [[MyButton alloc] initWithFrame:CGRectMake(x,y,w,h)];
    [aButton.titleLabel setFont:[UIFont fontWithName:@"QuicksandBook-Regular" size: 17.0]];
    [aButton setTitle:[currentDisplayArray objectAtIndex:i] forState:UIControlStateNormal];
    [aButton addTarget:self
                 action:@selector(didPressButton:)
   forControlEvents:UIControlEventTouchUpInside];
    [aButton setUserInteractionEnabled:TRUE];
    NSLog(@"width of button = %f height = %f", [aButton frame].size.height, [aButton frame].size.width);
//I printed this to check the height and width were generated correctly.
    [btnContainerView addSubview:aButton]; //UIView hooked up to storyboard
    [buttonArray addObject:aButton]; //Array to maintain reference to all buttons
}

Remember, they all display correctly, its just the ones that aren't rendered in the initial frame don't trigger the "didPressButton" selector.

-- Edit --

After playing around, I think its some kind of issue with the UIScrollView it is in. Is this some kind of apple bug? I even tried adding the gesture recognizers in the scrollViewDidScroll function.

-- Edit -- Another interesting hint, If I make the UIScrollView bigger, I can click more of the buttons, if I make it smaller I can click less. It definitely has something to do with the first rendered buttons.

Maybe iOS says its initialising the buttons, but doesn't keep the selectors of all 200+ buttons in memory. Or has an inbuilt number of possible selectors/gesture recognisers per class.

2
could you share some code please? At least the part where you programmatically create the buttons. - Nicola Miotto
Please check have you added (:) behind your method - Pradhyuman Chavda
Yes, i have a parameter going to my selector method, thanks. - FaddishWorm
Try changing your button code. You don't create buttons with alloc/init. Instead use: = [UIButton buttonWithType:]. Then set the frame with setFrame. Or use auto layout which you should be using now anyway :-) - CW0007007
@CW0007007 I tried this but it didn't work unfortunately. :( - FaddishWorm

2 Answers

1
votes

Yay, I worked it out.

There was a UIView sitting in front of the UIScrollView that the buttons were being added to.

The views were the same size, but only the buttons that were inside the initial bounds (the UIView size) were clickable.

There was a UIView that I think was called btnContainerView or something. What was happening was the buttons were being added to this UIView instead of the UIScrollView.

I think the UIView was set as the delegate for the buttons because thats were they were rendered. So when the UIScrollView received an input the buck stopped there. Calling addTarget:self on the buttons would mean their target was added to the scrollView, but they were rendered onto the UIView. A confusing bug because you would expect the UIScrollView not to scroll and render properly but it did, its just the delegates for the selectors were getting confused.

Thanks everyone for the help, this was quite tricky because the buttons scrolled correctly (UIScrollView got touch input) but the UIButtons didn't get the touch input.

TL;DR; The solution was removing the intermeditary UIView as it was interfering

-1
votes

I hope that you are using gestures int the view controller, if so you can use the below code

  - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
        if (([touch.view isKindOfClass:[UIButton class]] && touch.view.tag==<Btn_Tag>)) {
            return NO;
        }
        return YES;
    }

When using the gestures, gestures will respond first rather than the button action.So, this code will help to move the responder the button's action.