10
votes

I got stuck with the strange behavior of UIScrollView that I cannot click on the UIButton after I enlarge the contentSize of the UIScrollView.

What I wanted to do:

  1. Show a form with using UIScrollView

  2. After clicking on the submit button, the scroll view will enlarge some amount of height to show further information.

  3. In the further information, I will place and show another UIButton(hidden at the beginning) in order to process to the next step.

The problem is that I placed the new UIButton to the enlarged area and the button is not clickable whereas I placed the UIButton to existing area(the initial frame of scroll view) then the button works normally. For both cases, the scroll bar of the scroll view performs normal behavior.(ie, the scroll end is the new content height)

Here is what I have so far:

  • A UIView xib (placed all elements inside it including the hidden button)

  • A UIScrollView (loaded the UIView xib into it)

UIView* view = [[[NSBundle mainBundle] loadNibNamed:@"view" owner:self options:nil] objectAtIndex:0];

[view loaded];

[scrollView addSubview:view];

  • After the submit button is clicked:

// offset = some amount;

[scrollview setContentSize:CGSizeMake(scrollview.contentSize.width, scrollview.contentSize.height+offset)];

// h = some amount before the end of the scroll view

CGRect r = nextBtn.frame;

r.origin.y = h;

nextBtn.frame = r;

[nextBtn setHidden:NO];

enter image description here

I have tried to change the clipSubviews attribute of scroll view but seems it is not working for my case at all.

Anyone knows how it happens? And is there any better methods to get this job done? (resize the scroll view and then place another button in it)

Any help would be great! Thanks a lot!

2
how about set button.frame = CGRectMake(button.frame.origin.x,scrollView.contentSize.height - button.frame.size.height,button.frame.size.width,button.frame.size.height) and see if button place at the end of the scrollView.johnMa
the button appears at the end of the scrollView but still not clickable. It seems that the area below the initial frame is not clickable...user3099152
Hey user3088152, did you find any solution?gaurav414u

2 Answers

-2
votes

I assume that the button is direct or indirect child of the contents view you load from the xib file.

The problem is because you changed the scroll view's contentSize but did not change the frame of the contents view. Superviews participate in touch hit testing. You can place a subview outside of its superview bounds and by default the subview will not be clipped but touch events will not be delivered to it because the superview checks during hit testing that the touch is outside of its bounds and rejects the touch. See UIView hitTest:withEvent: for details.

-2
votes

You can add a button say submit and another button as subview of the scrollview.Keep your another button hidden in start and call setContentsize. now when user clicks on submit button then set another button to visible and again call set content size.In this way you would be able to achieve what you want to.

i have tried to generate scenario for you.I have tried this on view based application with storyboard without auto layout.

so in story board do some thing like this:

#import <UIKit/UIKit.h>

@interface ALViewController : UIViewController

@property (nonatomic, weak) IBOutlet UIScrollView *scroll;

@property (nonatomic, weak) IBOutlet UIButton *btn1; @property (nonatomic, weak) IBOutlet UIButton *btn2;

=========== implementation:

#import "ALViewController.h" 

@interface ALViewController ()

@end

@implementation ALViewController

- (void)viewDidLoad 

{ [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self.btn2 setHidden:YES];

[self adjustContentSize];

}

-(void)adjustContentSize { CGRect contentRect = CGRectZero; for (UIView *view in self.scroll.subviews) { if (![view isHidden]) { contentRect = CGRectUnion(contentRect, view.frame); } }

self.scroll.contentSize = contentRect.size;

}

  • (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }

-(IBAction)btnClicked:(id)sender { UIButton *btn = (UIButton *)sender; if (btn.tag ==1) { [self.btn2 setHidden:FALSE]; [self adjustContentSize]; }

}

@end

and in storyboard some thing like this:

enter image description here @end

for your information:view frame 0,0,768,1024 scroll frame: 0,0,768,1024 btn1 frame: 361, 753, 46, 30 btn2 frame: 351, 1032, 46, 30

run your code : at first your scroll view would be unscrollable because we have set btw 2 to be hidden and set content size.As soon as you will be clicking on btn 1, see code we are making btn 2 visible again and calling set content size.

Conclusion:

the scrollview content size looks for its visible contain of which we can take benefit of.

thanks and regards.