So I've been using size classes in Xcode 6 beta. I started out by putting some buttons in the middle of the screen in the AnyxAny base class. They showed up on the right side of the screen when I then ran the app in the iPhone simulator. To fix this, I went into the compactxregular size class and dragged the buttons to the middle and spaced them out a little. Then, when I ran it in the simulator, nothing had changed. Why? Is it just a glitch in the beta version or am I not doing something right? It worked when I added a center x alignment constraint to the buttons but I still wanted to do some spacing. (and also, what's the point of the size classes if I could just do it using constraints?)
The size classes are important so you can add individual constraints per size class (using the same storyboard). It has the flexibility to allow you to share certain constraints between all sizes devices and orientations, or just a single.
Click on each constraint you add and on the right menu, you can toggle which size class you'd like to add the constraint for. (It's the + button next to the installed check marks)
You can specify different constraints for different size classes. Watch the WWDDC 2014 video View Controller Advancements in iOS 8 to see how to do it in IB. If you can specify the layout you need without size classes, don’t bother; they’re just for overrides.
Related
I am using AutoLayout and Size classes, but with release of iOS 10 and new Xcode 8.0, there is one new option Vary for Traits. Is this replacement of Size Classe for different width and height of devices.
By selection of width checkbox, it displays varying 14 compact width devices.
By selection of height checkbox, it displays varying 18 compact height devices.
By selection of both checkbox, it displays varying 11 compact width regular height devices.
How to make use of this options ?
Can we use AutoLayout with size classes as like Xcode7.0 ?
If any one has in depth knowledge then please explain it.
This is just an extension as to how to use "Vary Traits" quickly in your project for adding different layouts for iPad and iPhones.
Please read this for understanding more on the Size classes.
https://developer.apple.com/reference/uikit/uitraitcollection
If you are skipping the example which follows below, do read the Summary in the end.
OBJECTIVE :
You need a button having different widths in iPhone and iPad. The former having width of 80 and latter having a width of 300.
METHOD 1 :
Vary for Traits with Multiple Constraints as installed.
STEPS :
Add the common constraints first like Center the button horizontally and vertically.
Choose VaryForTraits and for iPhone screens as per the size class guidelines , a C*R size class fits the model and this we check the tickmarks of Width & Height in PopUp. Dismiss the pop-up by clicking anywhere on screen.
Add the width constant and check whether the constraint is added for C*R size-class. After adding constraints, choose Done Varying button.
For iPad screens, again select any iPad device and choose VaryForTraits and this time on clicking height-width, it should show R*R variation.
Again add a width constraint, the last added iPhone width constraint must be unhighlighted as in the screenshot. The value added will be for the size-class R*R this time.
Switch back to iPhone layout and it takes 80 as width and iPad will take 300.
CONCLUSION :
Please notice that there are total of two constraints added and in both the constraints, the values differ according to the size-class chosen.
METHOD 2 :
Vary for Traits with Single Constraint , Multiple Size-Class installed
STEPS :
Add the normal width constraint. Then select that constraint and choose the + button besides the Constant value.
Add trait variation, and for iPhone we choose C*R and set the constant value as 100.
Again for iPad which follows a trait variation as R*R, we add another variation by clicking again on + button and set the value as 300.
Select an iPad and the width will be automatically taken as 300 and coming back to iPhone it takes 100 as value.
CONCLUSION :
This seems to be a better option rather than adding two constraints when a single constraint is only required and the constant value differs.
WHEN TO USE, WHAT TO USE :
Both the approaches are basically doing the same thing, setting values to Size-classes.
But, #Method1 is used when you want to add a constraint specifically for a device or say size-class. For example, in iPhone the button should be from Top 50 pts and in iPad it should be centered horizontally and vertically. In such situations, you need to use VaryForTraits as it opens doors to add constraints for a specific size class.
#Method2 is used when you want different constant values for a same constraint type.
P.S : TO ALL THOSE WHO ARE NOT ABLE TO GET THE EXAMPLE WORKING
Please make sure, you are adding only the required constraints as Installed. The checkbox against Installed should only appear for the constraint that you need for a size class. That is the key!
Just add a top constraint & a leading to an uiButton in a view. Select the top constraint and uncheck the basic Installed option with Plus sign. Now, by clicking on the Plus sign, add variation to CR and check that option. Now, change the device from iPhone to iPad with various orientation combinations. This constraint will be applied only for CR size class which is iPhone in portrait orientation. If the checkbox against the basic Installed (the one with Plus symbol) was checked that means the constraint should be applied to all size classes.
SUMMARY :
Trait Variation is a change to the presentation of your user interface that is based on a device configuration. Trait Variations of the user interface is not just limited to constraints but can be applied to much more. Such as changing the color of the background and other elements when the device is set to a dark style. A variation can apply to an element of the user interface, such removing a constraint, or to a property of a view class or constraint, such as the font for a label. You can vary:
Size or position of a view
Installation of a view
Installation of a constraint
Constraint constant
Font
Color for the font, tint, or background
Layout margins
Image file
The specific set of properties you can vary depends on the class of the element. In the example, we have demonstrated the use of- Installation of a constraint & - Constraint constant . Others, are quite simple and can be easily inferred.
Vary for traits is the evolution of size classes option that was present in the past version of Xcode. It allows a much more nifty and precise variation based on traits. Of course, it is not limited to iPad/iPhone only variations but you can specify also variations based on orientation and different device.
Other answers in this thread have some lacks and inaccuracies, perhaps the most efficient way to give an answer is to make an example. For the sake of clarity we will limit our example to only a button and two layouts. However, as explained below, you can extend the following example as you wish. Our goal is to to adjust the position of a button between two different layouts: landscape and portrait on all devices.
Note: If not enabled “vary for traits” option, all layout and ui interface adjustments are referred to all traits (ie. all size classes).
Let’s start by putting a button on our storyboard. Since “vary for traits” is not enabled, the button will be present in all different layouts. If, instead, we had enabled vary for traits the button would be referred only to the particular trait selected.
Now, let’s enable “vary for trait” and choose a variation based on height. You should see that the bottom screen will turn in blue and according to the selection you will see all the device impacted. So far, so good.
Select again the button and add the constraints ad usual. In our example, we will add top and left leading space as well as width and height. After that, click on the “Done Varying”. You will see that the bottom part of the screen will turn gray again. What is happening is that we have told Interface Builder to add the above constraints only for the (w:C h:R) classes.
Now select the landscape mode on the bottom of the screen. You will see that the Button is in red, because it lacks the constraints that you have added only for some traits. Select again vary for traits and select again the height variation. Add the following constraints:
and press done varying. Now the button is well identified on the screen both for landscape and portrait.
Build and run. You will see that the button will change according to the orientation of the screen.
You can create more advanced layouts following this pattern. For example, you can select at the beginning a vary for traits and drop UIKit objects only for a specific trait. This object will be present only in the specified variant and will be greyed out on the others one allowing you to create completely different user interfaces based on traits.
It is nothing but size classes it self but with different representation. till xcode 7 we used size classes and we consider height-width in regular,compact and any manner, in vary for traits concept is same but xcode specifically explain exact device. In older version we know that for every iphone in portraint etc kind of information where in this we can know exact device!
Check the below screen shots,
You should refer wwdc2016 - video for more information!
Reference : This So Post
I need to create an app with adaptive UI. for that I use auto layout and size class. but i can't get the expected result. it displays different UIs for different screen sizes. kindly guide me to create the adaptive UI(for all screen sizes). Thanks in advance.
This is indeed problem with constraints as mentioned in comments to your question. Using size classes only allows you to set constraints for all iphones at lowest level (that's why screen size for size class Compact x Regular is same for all iphones in xcode).
It is difficult to help you, without knowing all of your constraints. My advice is, use Preview assistant, where you can see all of your devices and generated UI. By opening this Preview assistant, tap on bottom "+" symbol and add device you wish to inspect.
As you can see on this screenshot, in my storyboard, there are margins around the middle view, however on iPhone 4, where width is smaller, these margins are lower (they have lower priority as constraint), while view retains it's width/height.
So I have created my webapplication and when I build it in xcode I have to under "Simulated Metrics" > "Size" set it to 3.5 inch since I have a iPhone 4s.
When I build it and run on the iPhone everything looks perfect, but I want this application to run on iPhone 5/6 aswell, but when I change the size to something else in the Simulated Metrics it gets really messed up on my iPhone. I'm using a webview of my responsive website which shouldn't really care about the screensize but I believe Xcode does. So, is there a solution where xcode automatically detects screensize and makes the webview take the whole viewcontroller? Or do I have to create a application for every screensize?
So, is there a solution where xcode automatically detects screensize
and makes the webview take the whole viewcontroller?
Yes - xcode provides ways to do this. Either through auto layout or using springs and struts. With auto layout you will define a set of rules that your UI will follow. If you want 1 layout for all devices it's fairly straightforward and any tutorial will get you started. with springs and struts you just tell your views how they should grow/stay put depending on screen growing. check this out for a quick introduction to auto layout: http://www.raywenderlich.com/83129/beginning-auto-layout-tutorial-swift-part-1
Or do I have to create a application for every screensize?
Nope.. but you can set different constraints in auto layout for your views to behave very different on different sizes. This gets a little more tricky..
No you do not make a new app for every potential screen size, instead you uses XCode's "auto layout" with a set of "constraints" controlling the size and placement of your widgets. A constraint can be a fixed size for the widget or a given distance relative to another widget (or the parent's border). It is not necessarily a fixed distance, it can also be "my widget needs to be less than 10 pixels apart from this other widget".
The "Simulated Metrics" you refer to in the bottom of the drawing area is only a visual help when laying out you your GUI, it has no effect at runtime. You can safely stick with "Any" width and height.
Read this tutorial to understand XCode's auto layout and constraints:
http://www.raywenderlich.com/50317/beginning-auto-layout-tutorial-in-ios-7-part-1
Quickly, these are the tools used to setup constraints:
In your case, assuming you have only one big view (your webview), you need to set up 4 constraints stating that the webview's left, right, top and bottom sides are 0 pixels away from the parent's left, right, top and bottom borders respectively:
Lay your webview in the middle of your drawing area
Click on it
Click the "pin" button; you will see this view:
Look at the upper part of the dialog: the small square in the middle represents the view you just clicked and the four red lines represent the distances to the parent's side. Set them all to 0 and click "Add 4 constraints". (Note: the lines are initially dashed when not selected; they turn into solid lines when activated.)
Now the frames in the drawing area do not represent what you were expecting: your webview is still in the middle where you placed it initially and does not fill all the available space; XCode is aware that there is a mismatch between the frames and the constraints and shows a warning. You need to update the frames: click the "issues" button and "update all frames".
The image comes from this question on SO:
What is "Constrain to margin" in Storyboard in Xcode 6
Read it to learn about the "Constraints to margin" switch.
I've been having such a hard time trying to figure out how this thing works. It's so random and I have no idea what else to try. I've looked up multiple articles on this issue and everyone just says change the scale. Changed the scale does not help, it's got nothing to do with what's happening here. I'm not sure if this is related to the bottom of Xcode where you can change the dimensions (Any vs Any / Any vs Regular Height, etc...) I've asked my mobile development teacher at school as well and he couldn't figure it out either. Any help would be greatly appreciated!!
Picture below:
http://tinypic.com/r/281fw5w/8
Your problem is not scaling. What you need to look at is auto layout and constraints.
You can use the icons in the lower right edge of the interface builder to get at them or control drag from a view controller (like a button, label, etc.) to the containing view (or any other view controller for that matter.) Usually, the main view window itself. When you release you can now add constraints to "attach" the element to that other element relatively. For instance, you could attach the things on the left to the left side and the things on the right to the right side. Now, regardless of the dimension of the actual device screen, those elements will appear in those locations relative to the device screen.
The problem is that the position of elements from your perspective is right for the canvas you see in the Interface builder, but once the app is run, the real canvas has different dimensions.
To manage the position, size and other attributes of UI elements, there is a system called AutoLayout.
It is quite ingenious because it is similar to natural language.
For example "I want this element to be in the middle of the screen."
or
"I want this element to be 20 pixels from the left corner and 57 pixels from the element that is above this element."
By combining these rules you basically create a set of layout constraints, that are applied in runtime to the view hierarchy and view are laid out properly.
Autolayout allows for very sophisticated layouts.
Another aspect you need to take into account that you might want your app to look well in all form factors from 3.5 inch iPhone up to iPad air.
Since these devices differ considerably in size, Apple introduced an abstraction called Size Class.
Size Class is an abstraction on top of concrete size. Concrete iOS devices have vey concrete dimensions. But in natural language you often say it's big ,or small ,or normal. And this the level of abstraction size classes use.
For each size class you can have a particular set of auto layout constraints.
So by combining AutoLayout and SizeClasses, Apple solved the problem oh how to have one application but one that can still accommodate specific form factors and can adjust its layout to them.
In Xcode6, all storyboards/xib files have autolayout & sizeclasses enabled by default. Interface builder provides you with a comfortable environment where you can set up your layout by creating constraints for each size class combination.
I want add one UIView – which has various number of UILabel objects – to a UIViewController.
How is it possible to set up constrains via auto-layout so, that if rotation occurs, and view width decrease, than height should increase, and labels should fit in like below, as CSS float do it.
Is it possible with interface builder and not programmatically?
UPDATE
Meantime I experimented iOS8 new interface builder feature called Size Classes (WWDC 2014 What's New in Interface Builder from 29:59), as matt has recommended down. But as I see, it supports something different, that I am looking for. Size Classes aim is to put different xibs (iPhone, iPad) into one xib, to have one xib instead of more.
In my case it does not help. What I have done to set up different auto-layout constrains for these two size classes:
But when I was running the application in iPad 4 simulator - what is the main target for my app - it used always the regular width / any height size class, and never the any width / any height, what my original expectation would have.
I do not know what "in a floating way" means. But in Xcode 6 you can easily do what you're describing, changing the constraints in an iPhone app so that the fourth label drops down to the next line, using the new conditional constraints (size classes) feature. With this feature, you can have one set of constraints for one set of size classes (e.g. iPhone in landscape) and another for a different set of size classes (e.g. iPhone in portrait).
Prior to Xcode 6, the answer would be no, you can't do that using IB alone. Code of some sort, whether a collection view or your own code responding to rotation/layout, would have to change the constraints.
With UICollectionView you can set up layout like CSS float.