The AutoLayout thing.

Source: Internet
Author: User

Transferred from: http://www.cocoachina.com/ios/20160530/16522.html

Articles submitted by this article, Mangomade (Pinterest)

AutoLayout is very powerful and very easy to use, readability is also very strong, plus a variety of third-party AutoLayout library, let you cloth like a chain of dogs! I can't stop it! of the previous

LABEL.FRAME.ORIGIN.Y + label.frame.size.height + 10

Now use only:

button.snp_makeconstraints{$0.top.equalto (label.snp_bottom). Offset (10)}

It's really good to not do it.

However, I used AutoLayout but met a lot of pits, read a lot of blog site to find I think the more good solution. I put these things out, if they are wrong, you can say in the message below, I hope that we can communicate a lot of common progress.

This paper mainly consists of four parts:

    • Updateviewconstraints and Updateconstraints Chapter

    • AutoLayout and Frame Articles

    • AutoLayout Animated article

    • AutoLayout Scale Setting

One of the words ' article ' embodies the author's pursuit of forcing lattice.

Updateviewconstraints and Updateconstraints Chapter

Basic usage

Updateviewconstraints and Updateconstraints are the AutoLayout of the new api,updateconstraints main function is to update the view constraints, The method of all its child views is called to update the constraint.

And the appearance of updateviewconstraints convenient Viewcontroller, do not have to rewrite the controller's view, when the view of the updateconstraints is called, If the view has a controller, the controller's updateviewconstraints will be called.

Two methods require that method of the parent class to be called at the end of the method implementation. And these two methods are not recommended for direct invocation.

In the process of use I found that these two methods are sometimes not called by the system. Later I saw the description of the bool method, public class Func requiresconstraintbasedlayout ():

constraint-based layout engages lazily when someone tries to use it (e.g., adds a constraint to a view). If you do all of the your constraint set up in-updateconstraints, you might never even receive updateconstraints if no one MA Kes a constraint. To fix this chicken and egg problem, override this method to return YES If your view needs the window to use Constraint-ba SED layout.

The main idea is that the view is not actively using constraint-based. In the case of non-constraint-based, the-updateconstraints may not be called at one time, and resolving the problem requires overriding the class method and returning True.

It is important to note that if a view or controller is initialized by Interface Builder, then the Updateviewconstraints or Updateconstraints method of this instance will be automatically called by the system. The reason should be that the corresponding Requiresconstraintbasedlayout method returns True. Instead, the pure code-initialized view Requiresconstraintbasedlayout method returns false by default.

So when you customize a view in a pure code, and want to write the constraint in the Updateconstraints method, you must override the Requiresconstraintbasedlayout method to return True.

As for the pure code write Viewcontroller how to make its Updateviewconstraints method be called. My own solution is to manually invoke the Setneedsupdateconstraints method of its view.

How do I use updateconstraints?

The most that is mentioned in the document for both methods is to override the two methods and set the constraints inside. So at first I thought the two methods were Apple's offer for us to write the constraints specifically. So I started trying to use it.

Until later in the UIView saw such a sentence:

You should only override this method when changing constraints on place is too slow, or if a view is producing a number of redundant changes.

"You should rewrite the secondary method only if you are too slow to add a constraint, or if you want to modify a large number of constraints at once. ”

It's just a feeling of confusion and a pit father. Exactly when the Updateconstraints method should be used

I later saw how-to-use updateconstraints this post. A reasonable explanation is given:

    • Try to write the addition of the constraint to a method similar to Viewdidload.

    • Updateconstraints should not be used to add constraints to a view, which is more appropriate for constraints that periodically update the view, or to write constraints to the method if the constraint is too expensive to add.

    • When we respond to an event, such as when a button is clicked, changes to the constraint are written to updateconstraints, which makes the code very readable.

On performance, I also made a simple test:

Class mmview: uiview {    override init (Frame: CGRect)  {         super.init (Frame: frame)          self.backgroundcolor = uicolor.graycolor ()          initmanybutton ()         //add constraint when initializing          test ()  //only one Test at a time () is not commented on     }     Override func touchesbegan (touches: set, withevent event: uievent?)  {        //adding constraints when responding to events          //test ()     }    override func updateconstraints () Add Constraints in  {        //updateconstraints          //test ()    &NBsp;    super.updateconstraints ()     }    func  test () {        let then =  Cfabsolutetimegetcurrent ()         addconstraintstobutton ()          let now = cfabsolutetimegetcurrent ()          print (Now - then)     }     Required init? (Coder adecoder: nscoder)  {        fatalerror ("Init ( Coder:)  has not been implemented ")     }    let  buttontag = 200    func initmanybutton () {         for index in 0...1000{             let button = uibutton (type: . System)             button.tag =  buttontag + index             Self.addsubview (Button)         }    }     func addconstraintstobutton () {        for index  in 0...1000{            if let  button = self.viewwithtag (Index+buttontag) {                 button.snp_makeConstraints{ make in                      Make.center.equalTo (self)                      make.size.equalto (self)                  }            }         }    }}

The setting constraints are written in Init, written in updateconstraints, time consumed in the event response method are tested, a constraint is added to 1000 buttons, and 4 constraints are added for each.

    • In Init, time consumption is approximately 0.37 seconds

    • Written in updateconstraints, time consumption is about 0.52 seconds

    • Written in the event response method, the time consumption is about 0.77 seconds

So, the conclusion is to write the constraint settings in Viewdidload or init. It's okay to try not to touch updateconstraints. Unless there is a requirement for performance.

About the Translatesautoresizingmaskintoconstraints property of UIView

Recently in the study of AutoLayout found that many people seem to translatesautoresizingmaskintoconstraints misunderstanding is very big, A lot of times there are people who will answer the following: Set the translatesautoresizingmaskintoconstraints to False to solve the problem ... Actually, it's not going to work.

So what exactly does this attribute do?

In fact, the name of this property has already explained the function of this property very clearly.

In addition to Autolayout,autoresizingmask is also a way of layout. This must be understood by everyone. By default, Translatesautoresizingmaskintoconstraints = True, at which point the autoresizingmask of the view is converted to the constraint of the corresponding effect. This is likely to conflict with other constraints that we have manually added. When this property is set to False, Autoresizingmask does not become a constraint. This means that the autoresizingmask of the current view is invalid.

So when do we need to set this property?

When we add a view in code, the Translatesautoresizingmaskintoconstraints property of the view defaults to True, but the Autoresizingmask property is set to. None by default. That is, if we do not move the Autoresizingmask, then the autoresizingmask will not have an impact on the constraints.

When we use Interface Builder to add views, Although the Autoresizingmask is set to None, the translatesautoresizingmaskintoconstraints is set to False by default. So there is no conflict.

On the contrary, some view is autoresizingmask layout, when we modify the translatesautoresizingmaskintoconstraints will let the view out of bounds, desperate. For example, when I customize a transition, I get the problem that the transition view is not in the middle of the view.

So, this property, basically we don't have to set it.

AutoLayout and Frame Articles

You may also use frame when using AutoLayout, such as when you need to use a layer.

So you might have this situation where you want the layer size to be set by other view dimensions, and this view is controlled by the constraints layout. If the initialization of the layer is placed in a method with the initialization of the view, similar to the method in Viewdidload

Layer.bounds = CGRectMake (0,0,view.bounds.size.widith * 0.5,50)

It is likely that the final layer width is 0.

This is because when the constraint is set, it does not immediately change the view, but waits until layout to modify the size of the views. Layout is usually when the view has been loaded onto the parent viewport.

So if we set a constraint in Viewdidload, the size of the view will really change when we wait for viewdidappear.

So, if you need to use both constrained layout and frame layout, if you can make them work well together?

A good solution is: The frame settings are written to Layoutsubviews or written in Viewdidlayoutsubviews. Because when the constraint is in effect, the center or bounds of the view is modified, the center or bounds is modified Layoutsubview, it is called, and then Viewdidlayoutsubviews is called back. At this point, the view frame that sets the constraint is no longer (0,0,0,0).

If we had to write the constraint and frame in the same way, we would set the frame after writing the constraint, instead of writing the frame to Layoutsubview (for example, we would like to calculate the height based on the result of the constraint as soon as we set the constraint). Then we can also manually call the Layoutifneeded method after the constraint has been set, so that the view immediately layout, update frame. After that, you can get the dimensions of the view where the constraint is set.

AutoLayout Animated article

The content of this article is very simple, that is, how the view of constrained layout is animated by displacement.

If one of our views is laid out by setting a frame, then we can change the frame directly when we animate the motion. Very simple.

In a constrained layout view, however, setting the frame is not an option. So what do we do?

There are a lot of people on the net way is: Get to do animation constraints, before the animation to modify the constraints, in the animation block call Setneedslayout method.

This method I feel very troublesome, in order to easily get the constraints, we usually also need to set the constraints to properties, animation more than that is the end of it?

A better way is to set the Transform property of the view.

For example, I want the view to be shifted by an x-axis +50,

Self.view.transform = cgaffinetransformmaketranslation (50, 0)

This can be set. Cgaffinetransformmaketranslation This method is to set the location.

AutoLayout Scale Setting

If we use AutoLayout to set the center of a view to the horizontal and vertical 1/4 of the screen:

button.snp_makeconstraints{Make in Make.centerX.equalTo (Self.view). Multipliedby (0.25) Make.centerY.equalTo ( Self.view). Multipliedby (0.25)}

This is equivalent to

Button.center = Cgpointmake (Self.view.bounds.size.width * 0.25, Self.view.bounds.size.height * 0.25)

So what does the multiple in AutoLayout mean?

Let view = UIView () self.view.addSubview (view) var. bottomconstraint:constraint!view.snp_makeconstraints {(make) in Mak E.height.equalto (Make.width.equalTo) make.centerX.equalTo (self.view.snp_centerX) Bottomconstraint = make.b Ottom.equalto (Self.view.snp_centerY). constraint}self.view.layoutifneeded () print (view.frame)//Printing results y:318 Height:50 and for 368bottomconstraint.uninstall () view.snp_makeconstraints {(make) in Make.bottom.equalTo (self.view.snp_ centery). Multipliedby (1.5)}self.view.layoutifneeded () print (view.frame)//Printing results y:318 height:50 and 552, just 368 1.5 times times/ So we can conclude that the multiple of a constraint on an edge represents a multiple of the distance from the edge to the opposite side//1.5 times times the code above makes the distance between the bottom edge and the y = 0 edge become 1.5 times times

The AutoLayout thing.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.