I'm actually facing difficulties to make my UIScrollView
fully responsive using only storyboard constraints.
Here is my hierarchy :
> - UIViewController
> - UIView
> - UIScrollView
> - contentView
> - module1View
> - module2View
> - module3View
All the modules are used to display charts. I want them to be responsive. I want their width to be 100% of the screen and their height is defined by a ratio added using constraint. The modules are displayed next to each other like news in a newsfeed.
My question is : How do you set the contentView
height equal to the sum of all the modules (module 1 + 2 + 3) ?
In other word I want to achieve :
- Top of contentView = top of module 1
- Top of module 2 = bottom of module 1
- Top of module 2 = bottom of module 2
- Bottom of contentView = bottom of module 3
To managed to do that I follow some tutorial found on internet. Here are the steps I followed :
- Setting
UIScrollView
contraints to define its place and position.
- Setting
UIScrollView
top, bottom, left and right spacing to nearest neighbour to 0.
- Setting the constraint between modules to "stack" them one on an
other.
- (I'M BLOCKED HERE) Setting the bottom of the
contentView
to the
bottom of module 3 to allow the UIScrollview
to scroll until the end
content.
I tried to force the height of UIScrollView
: It works but it's not responsive. As the height of the module is calculated through a ratio, depending on the device, the height "module 1 + 2 + 3" while change.
I tried to add a constraint from module 3 to contentView
to set the bottom of module 3 = bottom of contentView
. All the constraints turn red with warning everywhere.
Do you have any idea to how to set height of contentView
based on a responsive content ? (Like "wrap-content in a way).
Thanks in advance for you help !
I've been able to get dynamic scroll views working entirely from storyboards, no code, with the following steps:
1) In the storyboard, add a scroll view and constrain its edges to the edges of the main view or in whatever way is appropriate
2) Inside the scroll view, add a plain old UIView as a container. Constrain it to all 4 edges of the scroll view, BUT ALSO add an equal width constraint relative to scroll view, and an equal height constraint to the scroll view
3) Very important: set a low priority for the equal height constraint, e.g. 250.
4) inside the container view you added in step 2, add your 3 modules. Constrain the top edge of the first module to the top of the container view, constrain the bottom edge of the last module to the bottom of the container view, and constrain all the in-between modules to the preceding module in the chain. This should give you your chain of unbroken vertical constraints inside the container view. You will also need to add whatever appropriate x positioning / width setting constraints to each module.
5) Build and run! Your scroll view content size should automatically be equal to the total height of all modules plus the spacing between them, and changing the module contents dynamically will update the scroll view content size via auto layout rather than requiring explicit code to calculate and update.
Try to define height of the modules runtime and add auto layout constraint for modules programmatically.
#define kDeviceHeight [UIScreen mainScreen].bounds.size.height
#define kDeviceWidth [UIScreen mainScreen].bounds.size.width
- (void)viewDidLoad {
[super viewDidLoad];
[self setScrollViewHeight];
}
-(void)setScrollViewHeight{
float module1_Height,module2_Height,module3_Height;// Calculate the height of modules over here and assign it to respective variables
float viewVerticalSpacing = 5; // Provides space between two views
float YAxis = 0;
module1View.frame = CGRectMake(0, 0, kDeviceWidth, module1_Height);
YAxis = YAxis + module1_Height + viewVerticalSpacing;
module2View.frame = CGRectMake(0, YAxis, kDeviceWidth, module2_Height);
YAxis = YAxis + module2_Height + viewVerticalSpacing;
module3View.frame = CGRectMake(0, YAxis, kDeviceWidth, module3_Height);
float scrollView_height = YAxis + module3_Height + viewVerticalSpacing;
scroll_view.contentSize = CGSizeMake(kDeviceWidth, scrollView_height);
scroll_view.frame = CGRectMake(0, 0, kDeviceWidth, kDeviceHeight);
}
For me, Daniel's solution was very helpful but not working.
Here are the updated steps :
1) In the storyboard, add a scroll view and constrain its edges to the edges of the main view or in whatever way is appropriate
2) Inside the scroll view, add a plain old UIView as a container. Constrain it to all 4 edges of the scroll view, BUT ALSO add an equal width constraint relative to scroll view's parent (highest view), and an equal height constraint to the scroll view's parent
3) Very important: set a low priority for the equal height constraint, e.g. 250.