iOS fixed width ScrollView - ios

I want to achieve the following with auto layout.
---------------------
| |
| |
| |
| ScrollView |
| |
| |
| |
| |
---------------------
| |
| Content |
| |
---------------------
The ScrollView has a width equal to the screen size and the content inside the ScrollView extends the screen. I do not want the user to be able to scroll horizontally.
I have tried
Put a View inside of the ScrollView and set both of them to have leading, trailing, top, and bottom constraints to 0. Then I try to dynamically set the width of the Content and ScrollView to the ScreenSize.
Simply surround my page's content in a ScrollView set it to have leading, trailing, top, and bottom constraints to 0. Then I try to dynamically set the width of the ScrollView to the ScreenSize.
Both of the following result in something like this...
Notice how everything is centered horizontally like I have set it up to be, yet the horizontal scrollbar is present and you can scroll into a blank screen.

You probably set the wrong content size for the scrollview and hence it is scrolling horizontally.
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, sizeOfContent);

Related

Making the controller extend with the amount of text in UILabel in iOS

I'm quite new to Swift and iOS. I'm working on just getting things working so ignore the terrible UI. At the moment my text runs off the screen of the controller and I would like it make it so that depending on how long the text is the controller will allow for scrolling to accommodate it.
How can I do this with Swift and iOS?
First, you should place all your subviews (UILabel, UIImage etc.) in a UIScrollView.
Then, you have two options:
Springs & Struts: Once the frames of all subviews are set you can update the scroll view's contentSize property so it allows you to scroll. You can do this preferably in viewDidAppear method as all the frames have their exact value in there:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
scrollView.contentSize = CGSize(width: view.frame.width, height: bottomLabel.frame.maxY)
}
AutoLayout: With Autolayout, you no longer need to set the contentSize property explicitly. Just make sure you set vertical and width constraints correctly so AutoLayout will infer the contentSize automatically. Your subviews inside scrollView should be laid out as follows:
Scroll View
----------------
| Top Label |
| ------------ | v:10pt
| |
| Image | image.width = view.width
| |
| ------------ | v:10pt
| Bottom Label |
----------------
You can download the test project and see the constraints I set in the Interface Builder.
Here is the result I got:
Put everything you want to scroll inside of a UIScrollView

How to evenly space two subviews around the center of UIStackView (iOS 9)?

How to evenly space two subviews around the centre of UIStackView in the vertical axis?
Currently both labels are next to the top and the bottom of the StackView. The stack view is the greyed area on the simulator screen shot.
How to make them evenly spaced?
|
|
[UILabel]
|
|
[UILabel]
|
|
I've tried different configurations, but I couldn't get the desired result.
Here is my current code:
let object = UIStackView()
object.translatesAutoresizingMaskIntoConstraints = false
object.alignment = UIStackViewAlignment.Center
object.axis = .Vertical
object.distribution = UIStackViewDistribution.EqualSpacing
Considering you have similar properties set to UIStackView (as mentioned in the question)
alignment -> Center
axis -> Vertical
distribution -> Equal Spacing
The solution can be achieved by introducing two empty views with height constraint set to 0 to both ends of UIStackView.
Explanation
On Adding two empty views of height 0, we are telling UIStackView that we have 4 views instead of 2.
Now UIStackView will add equal spacing between all the views and hence the output.
You can cross verify it by looking at the height of the UIStackView and the position of the labels.
Hope this helps !!!
In stackView attribute inspecter change spacing value from 0 to your preferred space value..

Set the position of a UILabel to center

I have a view on that view I have a button and a label but the label will not align to be in center why so ever, its always on the right hand side of the view ....
pic what constraints I have set
Remove center X constraint, you have trailing/leading for that. After this your UILabel will be centered in the superview, but the text inside won't:
| [Text ] |
To center text, just set UILabel'stextAlignment to NSTextAlignmentCenter (centered), so it will be like:
| [ Text ] |
Also I suggest to remove forced height constraint (you have it set to 28) and replace it with something like top/bottom space or like that.

Horizontally align UILabel and UIImageView together inside of a full width UIView

I have a UIView in my layout that is pinned to the sides of my VC. Inside of that I have an icon UIImageView and a UILabel that is next to that. I would like both of those to be center aligned inside of the UIView no matter how long the text inside of the label is. (Similar to how you would use text-align:center; in CSS to align both image and text center).
| UIView |
| |
| |
| |
| |image| |label| |
| |
| |
| |
| |
Sometimes the label might be long, but I still need them centered:
| UIView |
| |
| |
| |
| |img| |label is long| |
| |
| |
| |
| |
I know how to use Autolayout but this one has me stumped since I can't created a "holder" UIView and center that. I need some help figuring out the constrains to add in IB.
Ideas?
Building on #Mahmoud Adam's answer, we can do this entirely in the storyboard.
Horizontal and vertical align the UIView relative to its superview.
Add constraints to the UIImage and UILabel so that they are pinned to the edges of the UIView.
The UIView will grow as the UIImage and UILabel grow inside of it.
Create a new UIView inside main view and put the UUImageView and UILabel inside it, this view should have the following constraints
using interface builder
Horizontal align inside the main view
Vertical align inside the main view (same as imageView now)
using code in the view controller
width = image.width + label.width + horizontal space between imageView & label
height = Max (image.height, label.height)
This is very simple i guess...using storyboard....
If you not found solution yet...then check this image and follow...
Here...green color background is UIView in image
and i select update constraints for view from resolve autolayout views

AutoLayout and UILabel resize animation not working properly on device rotation

i have a strange problem on a very simple task.
I needs a very small setup to reproduce the problem:
|--------------------------------------|
| Parent View |
| |
||------------------------------------||
|| UILabel ||
||------------------------------------||
| |
| |
||------------------------------------||
|| UIView ||
||------------------------------------||
| |
| |
|--------------------------------------|
In the example above we have a parent view with 2 subviews --> A UILabel and a simple UIView. Im using autolayout to apply the layout shown above:
Constraints for UILabel:
Leading Space to superview = 0
Trailing Space to superview = 0
Fixed Height constraint (e.g. 80pt)
Top Space constraint (e.g. 50pt)
The UIView subview has the same constraint types (the values for height and top space differs).
So what i expect with this setup, is that both subviews will adopt the full width of its parent as we defined that leading and trailing space should be zero. so if change the width of the parent view, the width of the subviews should change too, to stay aligned.
lets say the parent view has a dimension of 200x400 pt. when i build and run my example in portrait everything looks ok. when i rotate to landscape, everything still looks fine. the parent views width and even the subviews width got larger. but now when i rotate back to portrait the uilabels width immediately gets its target width without any animation:
|--------------------------------------|
| Parent View |
| |
| (immediately has target size) |
| |--------------| |
| | UILabel | |
| |--------------| |
| |
| (this subview is still |
| animating its width) |
| |------------------------------| |
|-->| UIView |<--|
| |------------------------------| |
| |
| |
|--------------------------------------|
the parent views width and the uiview subviews width are animated properly. its only the uilabel that has a strange behavior here and i cant find out what causes that issue.
My suggestions are:
If you've subclassed the parent view use the - (void)layoutSubviews:
- (void)layoutSubviews {
label.frame = CGRectMake(leftInset, labelY, parentView.frame.size.width - leftInset*2, labelHeight);
childView.frame = CGRectMake(leftInset, childViewY, parentView.frame.size.width - leftInset*2, childHeight);
}
if you didn't subclassed the parent view you can use autoresizingMask:
label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
childView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
The problem is not that the UILabel is not animating its resize but that the text does not animate. If you were to give the label a different background color, you would find that it does indeed animate, and it is just the text which jumps to position.
One way to fix this would be to change the width of the label with no animation and move it ober by X points, where X is half of the difference between the starting and ending width, and then just animate its position.
The only problem with this method for your code is that I do not believe you will be able to do it with auto layout.
As I remember, for constraints you should provide some more specs, but for such easy UI elements I would suggest using UIViewAutoresizing masks. They are much simpler and have shorter definitions. In your case just use UIViewAutoresizingFlexibleWidth.
Its better to set autolayout in story board. Please ensure that you are all the sub views is selected in your view controller when you are setting constraints. For that you should do the following:
Click on the view of your main view controller
Press Ctrl+A
Click Resolve Auto-layout Issues
Select Add missing constraints in Your View Controller
Then constraint will be set to all the subviews and will work perfectly during rotations.

Resources