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:
Show a form with using UIScrollView
After clicking on the submit button, the scroll view will enlarge some amount of height to show further information.
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:
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];
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!
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.
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:
@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.