I've figured out auto layout for the most part to get my storyboards loading nicely on both iPhones and iPads.
The only issue I'm having is button and label text.
They don't seem to size properly according the screen size.
I've got the width and height of them to scale based on a multiplication factor.
How could I do that with the text size?
I've tried putting this in the viewDidLoad
signup_btn.titleLabel!.adjustsFontSizeToFitWidth = true
signup_btn.titleLabel!.numberOfLines = 1
text_lbl.adjustsFontSizeToFitWidth = true
text_lbl.numberOfLines = 1
login_btn.titleLabel!.adjustsFontSizeToFitWidth = true
login_btn.titleLabel!.numberOfLines = 1
But that hasn't solved anything.
There are three main approaches to laying out a user interface.
You can programmatically lay out the user interface.
You can use autoresizing masks to automate some of the responses to external change
Or you can use Auto Layout.
Traditionally, apps laid out their user interface by programmatically setting the frame for each view in a view hierarchy. The frame defined the view’s origin, height, and width in the superview’s coordinate system.
To lay out your user interface, you had to calculate the size and position for every view in your view hierarchy. Then, if a change occurred, you had to recalculate the frame for all the effected views.
Other option is AutoResizingMask but you cannot use it for complex user interfaces.
Auto Layout represents an entirely new paradigm. Instead of thinking about a view’s frame, you think about its relationships.
I would highly recommend you to go through the following documentation - https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/#//apple_ref/doc/uid/TP40010853-CH7-SW1
This is an example for buttons without auto layout.
Also if the button and label position issue is occurring for only few screens then make different storyboard for these screen which doesn't have auto layout and different storyboard with auto layout.
Hope this will help you.
Related
I have some issues when i launch my swift application on ipad simulator. I have a home view witch displays 5 images. In my storyboard i have set for all of those constraints for height, width and also spacing. The problem is that when my app is running from ipad , the photo on the middle is situated over the other ones and the spacing is not as i expected.
What i want is a way i can make the same space value between images for each screen size and that the images will resize themselves in order to respect the initial view. Any piece of advice is more than welcome !^.^
Remove width and height constraints for your image views and add equal width and equal height constraints to them. Check out "Auto Layout Tutorial" section "Fixing the width" to see how to set equal width between views. I recommend you to read it whole :)
Nikita is right.
I can add: often apps evolve, so you will add another image.. far better to pass to a CollectionView where every CollectionViewCell owns an image.
In this way:
1) you can decide layout very precisely (with constraints in InterfaceBuilder, or form code using NSCollectionViewFlowLayout delegate methods..)
2) You can manage rotation easily
3) You can scale for iPhone..
For example, on a UIView, from left to right there are three buttons:,button1,button2,button3.
When button 1 become wider, such as its width become twice as its original width, is there any interface builder way that can make button2&3 move right automatically?
sorry for I didn't make my question clear.
I mean such kind of size change: I push button1, then I change it's frame in my code, not caused by the change of text in butotn1. I want button2&3 to move right automatically, keeping the width of the gap between button 1 and 2 unchanged.
Thanks everyone.
IB can be used only for initional positioning of views.
True, you can also define autoresizing masks of the views but that's about it.
Any additional laying out should be done in code.
I could be wrong, but I don't know of any way you can do this in IB. It's pretty straight forward in code though, just link the buttons to some IBOutlets and check the sizes of the images of the buttons (myUIImage.size), then adjust the frames of the buttons (do it in viewWillAppear).
Seen your edit - if you're adjusting its size using code, adjust its position too.
If your buttons are in a row at the bottom of the screen, consider using a UIToolBar. Its UIBarButtonItem objects automatically adjust to fit each other's width changes. For more generic cases, you'll need to recalculate positions and sizes as in Franklyn Weber's answer.
Yes - by using autoresizing masks. If you allow the margins to be flexible (no red lines connecting the frame to the superview's frame) and allow flexible width and height, the buttons will size and move proportionally.
I'm designing the UI with IB with a lot of images, and the default design orientation is landscape. However, I need to shrink the whole view to fit in portrait mode, by shrinking to the maximum allowed width and maintaining same aspect ratio for the view with it's inner images. The best way to imagine what I want to achieve is to imagine some landscape photo. When you rotate that to portrait it shrinks to the maximum width, centers vertically, but maintains the same aspect ratio. In my case, I want to shrink a view with its all inner subviews.
First, I'm manually resizing view frame to required size in viewWillApppear, and also calling setAutoresizesSubviews to resize all it's inner views. Those inner views - images are with "Aspect Fit" and all autosizing options set (to fill the available area on resized view). However, inner views pops out of the container: some images jumps to the top, text view expands to full portrait height. Is possible to set some kind of "view-container", then say - "view resize to size X and resize all your but only inside view-container area?
When you design in IB you must check several things. First of all the "view container" properties, that is the view that contains all subview. In order to behave properly on rotation this view must be setup with right IB Autosizing properties, that is with the autosize lines (springs) and border lines (structs) correctly set. In your case you want your container to be exactly fit with the main view so enable the "structs" at the four sides and enable the "springs" inside. Play with this values and look at the "Example" displayed by IB.
Then you must instruct this container to properly behave with its subviews. So check in IB that "Autoresize subviews" and the content mode, if needed, (= "Mode") has the wished setting.
At this point you check in the device or the simulator if your view is rotating and rising properly.
Then you must take care of the content of this view, which is a UIImageView. This must be centered, so remove the structs, and autoresized, so set the springs. Then set the content mode to Aspect Fit or Aspect Fill at your wish.
These settings should work. For more complex stuff, you must programmatically set things.
I have an app with a primary view that has a UITabBarController with 5 tabs. Each tab is a UINavigationController.
In interface builder, I'm customizing the background of each page by dragging a UIImageView and setting it fullscreen. The image I'm setting to the view is 640x960. I am setting it to be Aspect Fill.
However, what I've noticed is that it is not where I would expect it to be. When navigating between by tabs, the image seems to be shifted down from where it should be.
Also, when pushing a new view to the navigation controller, the background of this new view isn't offset in the same way as the tabbar one, and it is also slightly dimmed.
How can I set my UIImageViews on each page to be aspect correct and fill the screen 1:1? Also, how does one disable the dimming when pushing a view to the navigation controller?
Thanks for any tips, and apologies if this is covered in another thread, I couldn't find an answer searching the site.
Assuming that you are using the IB to setup your views, you should select navbar/tabbar options to reflect what will be on the actual page. That should place your image correctly. I would also recommend that you make both a low res and hi res version of your background images -- 320x480 and 640x960. Of course, your size may need to be adjusted (reduced) for the navbar and/or tabbar which will leave less than 960 px of vertical height -- probably more like 920px if you are in portrait mode. Then you add #2x to the base name of the hi res version, this would account for older iPhone screens.
Once you have the image placed correctly, resizing should be unnecessary. You can have the image automatically resize width and height using the little arrows on the layout page -- that's a bit hard to describe. It can also be done in code -- if you still need that I can provide a sample.
Maybe you need to set all AutoresizingMask in order to resize the UIImageView properly on each view. And to main aspect ratio u should use either AspectFill or AspectFit on the contentMode.
I have a view that supports landscape and portrait viewing, with the controls all moving around when you switch from one to the other. I'm currently doing this by setting the .center of each one of my controls when the user rotates the phone. The problem is that this is tedious, and requires a lot of code, and seems to defeat the purpose of using Interface Builder in the first place.
My question is: is there a way in Interface Builder for one view to support multiple looks (one for landscape one for portrait)? If not how do other people do this with IB? Do you set up 2 views?
Edit: Just to clarify my landscape and portrait views look different, I don't want a straight transform, I actually display the data differently in landscape mode
When necessary, I add UIView objects to the view in IB which I make hidden. Give it a nice background color so you can see it, and send it all the way to the background. Then use that view's frame when you need to set the frame of an object. If you have a lot of them, you might consider using UILabel instead, so you can give it a visible name in IB.
If you're worried about memory issues, just remove all these extra UIViews in ViewDidLoad and just store their frame values in member CGRects. This only works of course if you don't have any of the views auto-resize or reposition on rotate, which you probably shouldn't anyway, in this case. I do this for resizing/repositioning for any reason, not just when the screen rotates.
I'm not 100% sure if it's possible, but have you considered using different view controllers for landscape and portrait?
The AutoSize attributes of IBOutlet objects in the Size Inspector of IB (command 3) give some pretty nice options for auto-stretching and positioning of items. You can control L/R and T/B screen positions and relative width and height. You can't get full control of the layout, but most of the basic operations are there.
The only way one view can support multiple orientations in IB is to set the autosizing mask of components to either scale and/or anchor to edges. To design a totally different layout for each orientation you need to design a portrait and landscape view separately (each in its own XIB) and switch between them programatically.