Size classes and auto layout for iOS development - ios

I am trying to create a simple UI that works on all devices (obviously) and I haven't had much success. The program consists of two labels, a button, an image view and a textfield, I am also using a universal storyboard.
I implemented a top constraint, horizontally centred and fixed the width and height for all labels, buttons and textfields. The only exception I made with the image view was that instead of implementing a top constraint, I used a bottom one instead as I have found that utilising the former would result in it being only partially displayed. I would then switch from the universal storyboard to one with base values. From their I would delete the existing constraints and add new ones after moving the UI elements to their new locations on the different sized screen.
When I run my app on an iPhone 4S, the layout, whilst mostly correct, is still not perfect (i.e. a label is far too close to the image). Does anyone know how I can make my layouts look correct? I have been following this guide, Adaptive Layout Tutorial in iOS 9.
Thanks so much for your help!
[Example of the constraints for the picture1

I am not sure how familiar are you with autolayout, therfore I'd suggest you watch Stanford university lecture regarding autolayout.
In short, according to the lecture and after looking at your picture, you should almost never set constraints with actual numbers. Use "Standart value" and when you can't choose "Standart value" write 0.
I'd recommend watching the above lecture and the rest of the examples in there.

Your label has 2 problematic constraints
1. Top space (30 points) to "how old is your dog"
2. Top space (28 points) to button
That means that your button is 2 points height (really small!!)
Or - because the button has already a fixed height, the label and the text field are too close (and maybe even overlaps the button)
You should delete the top space constrain (to "How old is your dog") and do something else, or give it more points height
Good luck!

Related

Constraints for universal storyboard on iPhones

I'm struggling a bit with constraints on iOS with the differents screens sizes nowadays.
I tried google and stackoverflow to find a solution but my english does not seem fluent enough to find an answer.
I got 4 buttons verticaly aligned, the first and the last one are constrained by the edges of screens (kinda easy). But I'm really struggling with the constrains of the 2 middle buttons. I can't find a way to make them equally spaced from the left and right buttons on every size screens.
Is there something easy and tricky to make these constraints right ? Or am I doing it wrong and should I try to do it programmaticaly ?
Thanks
Add three invisible views in middle of each button, make their width equal with each other with constraint then your four buttons will be equally spaced. For the Y then you just need to pin it at your desired place.
If you are going to support only iOS 9 and higher, then use a UIStackView.
The solutions to this problem is very simple. This can be solved using the concept of "spacer views". You have to place invisible views between each red coloured view. You would be requiring 3 in your case. Then make their background as clear colour. .
Next, make their width equal and constrain their edges to the views that are after and before that view. You then define the size for red coloured view.
REMEMBER dont give the "clear coloured views" any fixed width. It would be determined by the runtime.This would solve the problem. Tell me if any more information is required.
Here is a blog post for the solution for this
http://adamdelong.com/fluid-layouts-with-auto-layout-size-classes-spacer-views-and-constraint-priorities/
This is the youtube video for this
https://www.youtube.com/watch?v=eSG-3-QpmWk&feature=youtu.be
Besides Tj3n's answer with views between buttons, you could use
A UIStackView (iOS 9!) where you use for settings Axis: horizontal, Distribution: equal spacing
A Toolbar (depends on what you want to do with your buttons) with toolbar items and flexible Space between them
Why not size classes? Apple introduced the concept of adaptive user interfaces in iOS 8 relying on a combination of Auto Layout and size classes.
If you aren't aware of what is size classes, there are plenty of tutorials available, please find one.
Summary: Apple very cleverly removed two story borads for iphone and ipad and made a single story board for universal app. No you dont have to struggle trying to apply autolayout constraint that satisfies all the screen sizes :)
Below are few of the size classes and their meaning :)
Regular width x Regular Height ----> iPad Potrait mode/ipad landscape mode
Compact width x Regular Height ----> iPhone 6 plus,iPhone 6,iPhone 5s,iPhone 5,iPhone 4s potrait mode
Compact width X Compact Height ----> iPhone 6,iPhone 5s,iPhone 5,iPhone 4s landscape mode
Regular width x Compact Height ----> iphone 6 plus landscape mode.
You can select the size classes you want to support from story board :) and start applying constraints specific to each size classes (like buttons in middle) or if you have generic one (like your buttons fixed to screen) for all the size classes.
You can deploy, remove, reuse or delete the constraints form various size classes.
SUMMARY: Buddy, If you are not using size class yet, its a high time to start using it :) There is a wonderful video on it in apple WWDC sessions 2014 i believe. Download, watch, start playing with it.
Happy coding :)
you can use equations to get this appearance.
use views' trailing points to get this.
View1.trailing = superview.trailing*(2.0f/9.0f)
View2.trailing = superview.trailing*(4.0f/9.0f)
View3.trailing = superview.trailing*(6.0f/9.0f)
View4.trailing = superview.trailing*(8.0f/9.0f)
if you make View1.width = superview.width*(1/9.0f) you can achieve what you want.
there are a lot of similar solutions for this issue. but the base is using trailing points.
It may also be done with using centerX positions of Views.
View1.centerX = superview.trailing*(3.0f/15.0f)
View2.centerX = superview.trailing*(6.0f/15.0f)
View3.centerX = superview.trailing*(9.0f/15.0f)
View4.centerX = superview.trailing*(12.0f/15.0f)
Thanks to LearneriOS answer, I solved my problem.
In order to get my wished result, I created 3 views with 10 width.
My first and my last button were already constrained. I constrained my first extra view to my first button with Horizontal spacing then i constrained my first extra view with the Center vertically in container. I then constrained my extra view to his own width and heights.
There come the important part: I did go on the constraint menus and selected the width constraint. The value inside was still 10 but I did change the priority from 1000 to 750.
Then I did copy my first extra view and constrained all of them to the nearest buttons, the same way I did with my first entra view but I removed their width constraint (to all the extra views but the first one) and constrained the extra views with the first one by plugging the: Equals Width.
Then I got my result, I hope it was clear enough and thanks again.

Auto height setting for labels in iOS

I have previously worked in Windows phone and see that every control in windows phone has an Auto property, meaning occupy the size of the content.
I see that in iOS such a property does not exist. When there are dynamic data to be bound to a UILabel, I always need to calculate the height of the data and then assign to the UILabel. This takes a good amount of time and bit painful. Is not there an Auto property or am I missing anything here?
iOS has AutoLayout which is really helpful, get familiar with it.
Click on the Label
Click on the pin constraints button (little square button)
Add your custom LEFT, RIGHT, TOP margins or LEFT, RIGHT, BOTTOM margins
Click on "Add 3 Constraints"
Set number of Lines to 0 which means as much lines as view needs
Then you probably got warning lines, but you can solve them
Just click on fix constraints button (little triangle button)
Click update frames
UPDATE
Important: the answer to your question is to PUT NUMBER OF LINES TO 0 you can use that UILabel with 0 lines(which is autosizing) with frames and AutoLayout. AutoLayout is just a friendly suggestion that can be helful to setup views. Also put Line Breaking Word Wrap
Here you go also with some useful links for working with AutoLayout. AutoLayout is great because you don't care anymore what size is the screen, what orientation has the device at that moment. You just need to setup everything correctly and everything works amazingly but if your setup is wrong then AutoLayout might become your enemy. So start learning and experiencing right now.
Very good point to Begin learning AutoLayout
If Your are being lazy, start from video tutorial series
Great iOS7+ table view tutorial with autoresizing cells
Also check out this Stack Overflow discussion
You need to familiarize yourself with Auto Layout:
Auto Layout dynamically calculates the size and position of all the
views in your view hierarchy, based on constraints placed on those
views.
Just give top, left and right constraints and make label's numberOfLines to 0. That's it. Label's height will resize automatically.

Not understanding auto layout, constraints and size classes

I'm a bit stuck and any help would be greatly appreciated!
I'll give you a quick overview. I have designs for a screen that were built in sketch using an iphone 6 screen size, then redesigned to fit and look right for an iphone 5/5s/5c, and 6 plus as those are the only devices that I want to support.
But the design portion or implementing the designs for just one specific screen size is easy and I understand that part. Where am I'm lost completely, is how to implement a design in one view controller that looks the way that it should in all the screen sizes I designed for.
I've gone through more than a few auto layout and size class tutorials and not sure how I properly use them so that the app recognizes "this is an iphone 5, use these image sizing and placements instead, and this is an iphone 6 plus, use these" and so on.
Everything I've seen to this point regarding auto layout and constraints only use 1 set of numbers to judge distance from elements for example, but all screen sizes would have different distances.
What am I missing or not understanding? I know I'm looking at something improperly.
Thanks in advance for all help!
You're correct that just one set of numbers could be used to judge distances, but this can still describe how a view should appear on different screen sizes. Your problem may be that you're thinking of constraints as describing the frame of your view? (Which obviously has to be different on every device). I find it more helpful to think of constraints as describing how each edge of my view relates to another view.
For example here's a view controller I setup with all the same constraints and how it would look on different devices. The constraints describe how the large grey view is pinned it's left and right edges 20 points from the left and right edges of its container view. It's pinned to 8 points from the top and 8 points from the top of the label. The label is centred vertically and horizontally and it has intrinsic content size. Each button is pinned 20 points from the bottom edge with button 1 and 2 being pinned to the 20 point from the left and right edges respectively.
I don't know if that helped or if that wasn't the answer you were after and you need to arrange your views differently depending on the device: you can tell Xcode which device size and orientation the constraints you're creating are for, using this button in Interface Builder.
Use it to select a device size/orientation. After, any constraints you create will only be used on that device. By default any width and height are selected so normally your constraints are applied to all devices.
Also, you cannot choose which devices you want to support, only the iOS version.

Popover not showing the content

I'm just trying to display a ViewController as a Popover, this is a small part of a big iPad application, and I've being trying to display the content with no success.
The worst thing is that if I create the same scenario in an empty/new project, it's works! The two View Controllers showed in the Image1 are completely new, I created those after tried to add a simple Popover action in one of my views I'm using in the App...which was not working. I tried with Clean and Build the Project more than once...just in case, but the same result. It's just not working in this specific project.
The two view controllers don't have Classes associated yet, I'm just trying to open the View2 when I click on the Button.
I appreciate your comments if I'm missing something really basic in this scenario.
(Adding more details)
I tried a different thing with the restrictions as you can see in the last two images, now I can see "something", but it's not respecting the positions.
You are using size classes of regular width & regular height (wRegular hRegular).
Design your popover view controller in Any-Any size and it should be OK.
(You can also uninstall the size classes of any object in that view controller)
There are some problems in your constraints.
The Label should have 3 constraints: left (Leading), right-to-the-text-field (Trailing) and top (Top Space):
The width and height are not needed because they are automatically set from the intrinsic content size of the label text ("Label").
IMPORTANT: When you add the constraints be sure that they are absolute, not margin related (to understand the difference read this blog post iOS8 Layout Margins).
The Text Field should have the following constraints: width and distance-from-top (Top Space):
Note that the second ("Leading Space") is the same of the "Trailing Space" of the label, not an additional one (the constraints are 5 in total).
You have to explicitly set the width of the text field (134 in my example) because otherwise the intrinsic content size will be set (and it is near to 0 because the text field is initially empty). The height is set correctly from the intrinsic size (calculated from font height, also if text is empty).
NOTE:
My answer implies some important Autolayout concepts. I advice you to study the Apple documentation to better understand them.
Hope this helps

Adjust Center of Measure in Xcode 6

In the new "Xcode 6" the ability to change the center of measure of a button is missing.
In Xcode 5: http://imgur.com/jWHJp4v
Xcode 6: http://imgur.com/rsNayVZ
When I put an item (like a button or label) somewhere, I am unsure of the center, so my code that deals with the item is incorrect.
The "center" shown here in Xcode 6 is measured from the top left of the item, not the actual center.
How should I fix this so it is measured from the center like here, in Xcode 5?
You can't “fix it”. That control is gone in Xcode 6. I suspect they removed it to encourage you to use constraints instead of setting frames directly. You can use constraints to pin the center, right, or bottom of a view.
It's driving me crazy that the origin widget has been removed. It has made the placement of any object relative to another very difficult. I always use auto layout and I'm not sure how this improves it. Also, I'm not sure I follow the logic of improving a feature by making it more difficult to use. In the past, it was very helpful to set the "anchor point" of the origin and then adjust the object's position or size and have the frame grow on the unanchored sides. Now i have to break out the calculate and add position + size and then add buffer space to figure out where next object should start. And if I adjust the first object's frame in any way I need to break out the calculator again. Once you have a few objects that are relative to each other, it becomes vary painful to tweak any object's frame without having to recalculating everything.
As a side note, the removal of the ability to delete a constraint right in the size inspect is also a confusing choice. Instead we have to go through the document outline and manually delete them there. This is not a big deal for the size constraints as they are keep in the object's sub-directory however finding edge related constrains is much more difficult as they are grouped with the rest of the edge constrains and can be difficult to find. Again, is this an example of encouraging / improving auto layout? Very frustrating!
The feature has been removed from Xcode. I believe this is to account for the various sizes of devices now available, and as a result, the use of constraints is the way to go.
If you are using auto layout then this two will help you place you control in center for all the view different size of devices.
simple:
http://technet.weblineindia.com/mobile/using-auto-layout-in-xcode-6-for-universal-ios-app-development/
Advance:
http://www.youtube.com/watch?v=G53PuA_TlXk&feature=youtu.be&list=UUtc1Jt_UTPsXpAGtvlr0nUQ
Apple has removed this feature as there are 4 different size of devices only for iphone and it would be difficult to set frame for all controller and will increase the length of code and will become a tedious task as it check's the size of device and then set frame so in XCode 6.0.1 we need to use auto layout + size class and prepare our view based on the constraints set in storyboard or Xib.
Hope the above link's will help in solving your problem.
If your layout isn't too complex you can "Pin" your button or view to the top or bottom, sides, etc.
Or you can do your constraints manually here:
The first method works really well and is super easy! I had a similar problem as you looking for tools that have been left out in Xcode 6 and found this wonderful tutorial on Auto Layout:
http://www.raywenderlich.com/50317/beginning-auto-layout-tutorial-in-ios-7-part-1
If you are trying to center it I would click on the button or view you are working on and look at the size inspector here:
Look at where I circled and make sure that the bottom space and the top space are equal to the same amount (mine aren't equal), but that should give you the center.

Resources