1. Basic Concepts
iOS devices have only one size before the ipad and iphone 5 appear. The only thing we need to consider when making screen adaptations is the direction of the device. Many applications do not support steering, so there is no screen-fit job at all. With the launch of the ipad and iphone 5, and the next iphone 6, the screen size has become an object to consider. Before IOS7, when making UI for an application, especially for universal, we always first think about the length and width of our target device, how the layout should change after the direction transformation, and then layout. IOS6 introduced AutoLayout to help developers use constraints for layout, which allows us to focus on using constraints to specify locations in some cases when we no longer have to consider dimensions.
Since we have a autolayout, it is no problem to specify the location and size of the view through constraints, and in this regard, the specific dimensions and orientations of the screen are less important. But this is not enough in combat, AutoLayout, just as its name, is a scheme based on constraints, and there is a lack of experience in the specific case of different devices. One of the most obvious problems is that it cannot determine different interaction experiences based on the type of device. Many times you still need to determine whether the device is an iphone or an ipad, and whether the device is in a vertical or horizontal direction. In this case, it is still difficult to get rid of the judgment and reliance on the equipment, and then, if there are new sizes and devices, the dependency is obviously very fragile (think of iwatch). )。
So in IOS8, Apple has overturned its original design philosophy and introduced a new set of ideas to adapt to the constant development of the device. This is sizeclasses.
They are no longer differentiated according to the specific size of the device screen, but are divided into normal (Regular) and compact (compact) two categories (class) through their sensory performance. Developers can ignore the specific size, but rather the two types and their combination of adaptation. In this way, both at design time and in code, we can no longer be limited to the specific dimensions, but instead become the visual senses that follow the dimensions to fit.
The sizeclasses has three values: Regular,compact and any. What does any mean? If weight is set to Any,height to regular, then the interface element in that state will exist in the state where the height is regular, whether weight is regular or compact. This relationship should be called an inheritance relationship, and the specific four interface descriptions and inheritable interfaces are described below:
1234 |
w:Compacth:Compact继承(w:Anyh:Compact,w:Compacth:Any,w:Anyh:Any) w:Regularh:Compact继承(w:Anyh:Compact,w:Regularh:Any,w:Anyh:Any) w:Compacth:Regular继承(w:Anyh:Regular,w:Compacth:Any,w:Anyh:Any) w:Regularh:Regular继承(w:Anyh:Regular,w:Regularh:Any,w:Anyh:Any) |
The size of so many devices (IPhone 4s,iphone 5/5s,iphone 6,iphone 6plus,ipad,applewatch) is simply expressed by sizeclasses:
Iphone4s,iphone 5/5s,iphone 6
Vertical screen: (w:compacth:regular)
Horizontal screen: (w:compacth:compact)
Iphone6plus
Vertical screen: (w:compacth:regular)
Horizontal screen: (w:regularh:compact)
Ipad
Vertical screen: (w:regularh:regular)
Horizontal screen: (w:regularh:regular)
AppleWatch (guess)
Vertical screen: (w:compacth:compact)
Horizontal screen: (w:compacth:compact)
PS: Attachment:
2, Uitraitcollection and Uitraitenvironment (Size classes handwriting code)
To characterize Sizeclasses,apple, a new class was introduced in iOS 8, uitraitcollection. This class encapsulates information such as sizeclass in horizontal and vertical directions. Most of the basic classes of UI in IOS 8 (including Uiscreen,uiwindow,uiviewcontroller and UIView) implement Uitraitenvironment this interface, Uikit Through the traitcollection of the property, we can get the corresponding Uitraitcollection object, so as to know the current sizeclass, and further determine the layout of the interface.
In contrast to the responder chain in Uikit, Traitcollection will be delivered from top to bottom in Viewhierarchy. For a UI part that does not specify Traitcollection, the traitcollection of its parent node is used. This can be quite useful when the layout contains the Childviewcontroller interface. Another very useful uitraitenvironment in this interface is-traitcollectiondidchange:. This method will be called when the traitcollection is changed. In practice, we tend to rewrite-traitcollectiondidchange in Viewcontroller: or-willtransitiontotraitcollection: Withtransitioncoordinator: Method (for Viewcontroller, the latter may be a better choice because the transition context is provided for easy animation, but for normal view there is only one way), The current traitcollection is then judged and re-laid and animated. The code will look something like this:
Overridefunc willtransitiontotraitcollection (Newcollection:uitraitcollection, Withtransitioncoordinator Coordinator: Uiviewcontrollertransitioncoordinator) {super.willtransitiontotraitcollection (newcollection, Withtransitioncoordinator:coordinator) coordinator.animatealongsidetransition ({(Context:uiviewcontrollertra Nsitioncoordinatorcontext!) -Voidinch if(Newcollection.verticalsizeclass = =uiuserinterfacesizeclass.compact) {//To do:modify something for compact vertical size}Else { //To do:modify something for other vertical size} self.view.setNeedsLayout ()}, Completion:nil)}
In two to do, we should delete or add or change autolayout constraints under different conditions (you can, of course, do anything else you want), and then call-setneedslayout to trigger the transfer animation in context. If you insist on working with code, you may have to face the problem of removing old constraints and adding new constraints to different sizeclasses, which can be said to be troublesome (at least I think it's going to be a lot of trouble). But if we use IB, these things and code can be omitted, we can easily specify various sizeclasses constraints in IB (we will show how to use IB to correspond to sizeclasses). In addition to the use of IB can not only save hundreds of lines of layout code, but also from the new Xcode and IB to get a lot of design can be real-time monitoring, viewing and debugging features. It can be said that the time-consuming and cost gap between the handwritten UI and the IB design has been further widened, and many of the handwriting UI has not been implemented, but IB can do it without hesitation. In this sense, the new IB and sizeclasses system can be said mercilessly to the handwritten code sentenced to a reprieve.
In addition, the introduction of new APIs and systems also sentenced the death penalty to many of our familiar uiviewcontroller of rotating old friends, such as the following API deprecated:
ReadOnly- willrotatetointerfaceorientation:duration:- Willanimaterotationtointerfaceorientation:duration:- didrotatefrominterfaceorientation:- Shouldautomaticallyforwardrotationmethods
Now all is unified to the Viewwilltransitiontosize:withtransitioncoordinator: the concept of rotation is no longer advocated for use. In fact, think about, the so-called rotation, but it is a change of size, we have been apple for many years, is not it?
3. Use sizeclasses in Interfacebuilder
Create a new generic project. If you want to be early in a XCODE6 project that has already been created, you need to activate the sizeclasses option. You can find it in the properties panel of Interfacebuilder by checking the AutoLayout option below.
First, let's look at the Sizeclass grid in Xcode. This is an area where you can switch between different layout arrangements. When you look at the storyboard, see the bottom of the view and click on the ' Wanyhany ' tab. You'll see some grid-like images.
By default, we start with a basic set of settings, namely Anywidth and Anyheight. Many things will be placed and changed here, including the default layouts for all directions of the iphone and ipad. Apple recommends setting most of the settings in this interface. This is particularly simple because of the reduced workload. Let's lay out a super wide button in the middle of the screen. Give it a green background so that we can see its true size and give it a restraint to center on it.
and gives it an exaggerated fixed width of 600.
OK, now that the ipad and iphone simulator are running, you will see the center, but for the iphone two directions are too wide, (here you set the width of the button in the page but not immediately update is because you do add constraints when you do not update the graphics, resulting in the situation , storyboard inside no update, and in the emulator run time update, left outline column inside also has warning explanation, can directly click the yellow triangle inside the warning to update the picture is actually updataframe)
Let's use sizeclasses to fix it. Go back to the grid of the first picture. Select the Portrait (portrait) setting of the iphone, which is the compact width + normal height. The red rectangle in the grid.
You will notice that the bar at the bottom is changed to blue after you select it in the grid. That is warning you: "Hey, you are not in a basic setting, and some changes will be displayed only when you are running." So this bar is now blue! "Some of the changes I've made are because there are four things you can change sizeclasses:1 constraint constants, 2 fonts, 3 constraints on/off, and 4 child views on/off.
The first two are self-evident, but let me show you how to make the latter two work. In the current Sizeclass (Compactwidth and Regularheight) situation let's try to close a constraint. In the outline section of the document, click on the Centrex calibration constraint set on our button:
Looking at our property check bar, we can see a tagged word "installed" at the bottom and an extra plus button on the left. Click on the additional plus sign and click ' compactwidth| Regularheight ' (the current is).
Now you will see 2 markers, which uncheck the one you just added (WCHR)
Now our constraints are no longer placed and do anything to configure Sizeclasses. As you can see, Xcode is accusing us of being too messy (the outline on the left has an error indicating that you are missing the constraint-translator), and if you run the app on the iphone emulator at this time, the button is not centered in the x direction. But it's still centered on the ipad, because the constraints are still placed in the basic settings. This constraint will always be configured unless we uncheck it. You can even rotate your iphone simulator and find that the button will magically go back to the center, because the iphone's landscape is different sizeclass configuration, OK, let's put the tick back and let the button back to the center.
Now let's change the constraint we set on the button width, select the button, and come to the property check bar of size, drop down to the bottom and we can see all the constraints. Click Width originally to be 600 using edit set to 100:
Run on the iphone emulator and you will see that the button has the correct width. When I ran the ipad simulator, it showed a width of 600 because we didn't change the width of the basic settings. However, the horizontal landscape on the iphone still looks bad because the iphone's landscape setting comes from the basic anyany settings. Let's fix it. In the grid we choose Compactwidth and Compactheight. The blue grid of the first picture.
Now we change the width constraint in this setting, just as we have changed for compactxregular. Give a width of 400. Run the iphone simulator and rotate to landscape, the button has a width of 400 and looks great. reached our expectations. One thing that's good is that you can see a list of all the constraints that are different settings. Just select the constraints you want to see in the document outline, and then come to the property check bar, and they are neatly arranged under the initial constants. It marks each one based on the settings it applies to.
Even if we decide we want to just disappear in the iphone landscape landscape mode, using sizeclasses we just reverse-place the views as if we were to place a constraint backwards. Select our UIButton and scroll to the bottom of the property inspector. Add a new placement option to our current settings by clicking the Plus button, then uncheck it.
As you can see, the view disappears immediately, because we put it back in the setup and we see it right away. Running the app, you can see it disappearing on the vertical portraitiphone, but back when you rotate to the horizontal landscape. Of course it has been placed on the ipad because the ipad is still using the basic settings.
4, Sizeclasses and Imageasset and Uiappearence
Imageasset also added support for sizeclasses, which means we can assign different images to different sizeclass. Select a picture in Imageasset's edit panel, Inspector now has a combination of width and height, add we need the corresponding sizeclass, and then drag the appropriate diagram up, This allows the SDK to replace the graph from which the corresponding size is selected at run time. Moreover, in IB we can also select the corresponding size to see the changes directly at the time of editing.
Actually it is too simple to do. But take a demo to explain it, such as the following this implementation of the compact in the vertical direction when the smiley face changed to cry--of course, a line of code does not need
In addition, a Renderingmode property has been added to UIImage in IOS7. We can use Imagewithrenderingmode: and pass in a suitable uiimagerenderingmode to specify whether the image should be rendered in the same way as the template. In the new Xcode, we can specify whether it needs to be used as a template directly in the imageasset renderas option. and accordingly, in uiapperance, Apple also added the appropriate method for our sizeclasses. Using the +appearancefortraitcollection: method, we can make very simple settings for the apperance of applications under different trait. In the example above, we want to make the smiley face green, and the cry is red, not too simple. First, the render option in Imageasset is set to Templateimage, and then the two lines are added directly to the appdelegate:
Uiview.appearancefortraitcollection (Uitraitcollection (verticalsizeclass:. Compact). tintcolor=Uicolor.redcolor () uiview.appearancefortraitcollection (Uitraitcollection ( Verticalsizeclass:. Regular)). Tintcolor=uicolor.greencolor ()
Size Classes with Xcode 6