UIView

UIView is an object that manages content for a rectangular area on the screen. Views are the basic building blocks of an application’s user interface, and the UIView class defines the behavior common to all views. The view object renders the content within its bounding rectangle and handles any interactions with that content.

The UIView class is a concrete class that you can instantiate and use to display a fixed background color. You can also subclass it to draw more complex content. To display labels, images, buttons, and other interface elements common to applications, use the view subclasses provided by the UIKit framework rather than trying to define your own view subclasses.

Because view objects are the primary way an application interacts with users, they have many responsibilities. Here are some:

  1. Drawing and animation
  • Views use UIKit or core graphics to draw content in their rectangular area.
  • Certain view properties can be set to animation with new values.
  1. Layout and subview management
  • A view can contain zero or more subviews.
  • Views can resize and position their children.
  • Use automatic layout to define rules for view resizing and repositioning in response to changes in the view hierarchy.

3. Event handling

  • A view is a subclass of UIResponder that can respond to touches and other types of events.
  • A view can install a gesture recognizer to handle common gestures.
  • Views can be nested within other views to create view hierarchies, which provides a convenient way to organize related content. Nested views create parent-child relationships between nested child views (called child views) and parent views (called superviews). A parent view can contain any number of child views, but only one parent view per child view. By default, clipping of subview content does not occur when the subview’s visible area is outside the scope of its parent. Change this behavior using the clipsToBounds property.
  • The geometry of each view is defined by its frame and boundary properties. The frame property defines the view’s origin and dimensions in its parent view’s coordinate system. The bounds property defines the internal size that the view sees, and is used almost exclusively in custom drawing code. The Center property provides a convenient way to reposition a view without directly changing its frame or boundary properties.

UIView common functions

– (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;

Initialize and return the newly allocated view object using the specified frame rectangle. The new view object must be inserted into the view hierarchy of the window to use it. If a view object is created programmatically, this method is the designated initializer for the UIView class. Subclasses can override this method to perform any custom initialization, but they must call super at the beginning of their implementation.

If the Interface is designed using Interface Builder, this method is not called when the view object is subsequently loaded from the NIB file. The objects in the NIB file are reconstructed and then initialized with their initWithCoder: method, which modifies the properties of the view to match those stored in the NIB file.

Parameters:

Frame: The frame rectangle of a view, in points. The origin of the frame is relative to the superview to which it is to be added. This method uses the frame rectangle to set the center and boundary properties accordingly.

Return value: initialized view object.

- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
Copy the code

UIView(UIViewGeometry) – View geometry

Commonly used attributes

@property(nonatomic) CGRect frame;

Property description: Frame rectangle that describes the position and size of a view in its parent view’s coordinate system. Use this rectangle during layout operations to set the size and position of the view. Setting this property changes the point specified by the Center property and changes the size in the bounding rectangle accordingly. Frame coordinates are always represented as points. Changes to this property can be animated.

If the transform property is not an identity transform, the value of the property is undefined and should therefore be ignored. Changing the frame automatically redisplays the view without calling its drawRect: method. If you want UIKit to call the drawRect: method when the frame changes, set the contentMode property to UIViewContentModeRedraw. However, if the Transform property contains a non-identity transform, the value of the frame property is undefined and should not be modified. In this case, the view is repositioned using the Center property and resized using the bounds property.

@property(nonatomic) CGRect            frame;
Copy the code

@property(nonatomic) CGRect bounds;

Function description: a bounding rectangle that describes the position and size of the view in its own coordinate system. The default boundary origin is (0,0) and is the same size as the rectangle in the frame property. Changing the size portion of this rectangle makes the view larger or smaller relative to its center point. Changing the size also changes the size of the rectangle in the frame property for matching. The bounds coordinates are always specified as points. Changes to this property can be animated.

Changing the bounds automatically redisplays the view without calling its drawRect: method. If you want UIKit to call the drawRect: method, set the contentMode property to UIViewContentModeRedraw.

@property(nonatomic) CGRect            bounds;  
Copy the code

@property(nonatomic) CGPoint center;

Function description: The center point of the frame view. The center point is specified as a point in the parent view’s coordinate system. Setting this property updates the origin of the rectangle in the frame property accordingly. If you want to change the position of the view, use this property instead of the frame property. The center point is always valid, even when scaling or rotation factors are applied to the transformation of the view. Changes to this property can be animated.

@property(nonatomic) CGPoint           center;
Copy the code

@property(nonatomic) CGAffineTransform transform;

Property description: Specifies the transformation applied to the view relative to its boundary center. Use this property to scale or rotate the view’s frame within the parent view’s coordinate system. (To change the position of the view, modify the Center property.) The default value of this attribute is CGAffineTransformIdentity. Changes to this property can be animated.

The transformation takes place relative to the view’s anchor point. By default, the registration point is equal to the center point of the frame. To change the anchor point, modify the anchor property of the view’s underlying CALayer object.

In ios8.0 and later, the transform property does not affect automatic layout. Auto layout calculates a view’s aligned rectangle based on its unconverted frame.

When the value of this property is not an identity transform, the value in the frame property is undefined and should be ignored.

@property(nonatomic) CGAffineTransform transform;
Copy the code

@ property (nonatomic) CGFloat contentScaleFactor API_AVAILABLE (ios (4.0));

Property description: Scale factor applied to the view. Scale factors determine how the contents of a view are mapped from logical coordinate space (measured in points) to device coordinate space (measured in pixels). This value is usually 1.0 or 2.0. A higher scale factor means that each point in the view is represented by multiple underlying pixels. For example, if the scale factor is 2.0 and the view frame size is 50 x 50 points, the size of the bitmap used to display that content is 100 x 100 pixels.

The default value for this property is the scale factor associated with the screen that is currently displaying the view. If the custom view implements a custom drawRect: method and is associated with a window, or if you use the GLKView class to draw OpenGL ES content, your view is drawn at the full resolution of the screen. For the system view, this property may have a value of 1.0, even on a high-resolution screen.

In general, you do not need to change the value in this property. However, if your application uses OpenGL ES for drawing, you may want to change the scale factor to sacrifice image quality for rendering performance.

@ property (nonatomic) CGFloat contentScaleFactor API_AVAILABLE (ios (4.0));Copy the code

@property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled API_UNAVAILABLE(tvOS);

Property description: A Boolean value indicating whether the view receives more than one touch at a time. When set to YES, the view receives all touches associated with the multi-touch sequence and starts within the view’s boundaries. When set to NO, the view only receives the first touch event in the multi-touch sequence that starts within the view boundary. The default value for this property is NO.

This property does not affect the gesture recognizer attached to the view. The gesture recognizer receives all touches that occur in the view.

When this property is NO, other views in the same window can still receive touch events. If you want this view to handle multi-touch events exclusively, set the value of this property and the exclusiveTouch property to YES. This property does not prevent views from being asked to handle multiple touches. For example, two child views might both forward their touches to a common parent view, such as a window or the root view of a view controller. This property determines how many touches that were originally intended for the view are passed to that view.

@property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled API_UNAVAILABLE(tvOS);
Copy the code

@property(nonatomic,getter=isExclusiveTouch) BOOL exclusiveTouch API_UNAVAILABLE(tvOS);

Property description: A Boolean value indicating whether the receiver handles touch events exclusively. Setting this property to YES causes the receiver to prevent touch events from being passed to other views in the same window. The default value for this property is NO.

@property(nonatomic,getter=isExclusiveTouch) BOOL       exclusiveTouch API_UNAVAILABLE(tvOS); 
Copy the code

@property(nonatomic) BOOL autoresizesSubviews;

Property description: A Boolean value that determines whether a receiver automatically resizes its subviews when its boundaries change. When set to YES, the sink resizes its subviews when its boundaries change. The default value is YES.

@property(nonatomic) BOOL               autoresizesSubviews;
Copy the code

@property(nonatomic) UIViewAutoresizing autoresizingMask;

Property description: An integer bitmask that determines how the receiver resizes itself when the boundaries of its parent view change. When a view’s boundaries change, the view automatically resizes its children based on the auto-resizing mask of each child view. You can specify the value of this mask by using the C bits or constants described in UIViewAutoresizing with the operator combination. By combining these constants, you can specify which dimensions of the view should increase or decrease relative to the parent view. The default value of this property is UIViewAutoresizingNone, which means that the view should not be resized.

When multiple options are set along the same axis, the default behavior is to distribute the size differences proportionally between the flexible parts. The bigger the flexible part, the more likely it is to grow compared to other flexible parts. For example, assume that this property including UIViewAutoresizingFlexibleWidth and UIViewAutoresizingFlexibleRightMargin constants, But does not include UIViewAutoresizingFlexibleLeftMargin constants and instructions from the width of the view on the left is fixed, but the width of the view and the right margin is likely to change. Therefore, as both the width of the view and the gap on the right side of the view increase, the view is anchored to the left of its parent view.

If the automatic resizing behavior does not provide the precise layout that the view needs, you can use a custom container view to rewrite its Layout Subviews method to position the subviews more precisely.

@property(nonatomic) UIViewAutoresizing autoresizingMask;
Copy the code

Enumeration of UIViewAutoresizing:

Typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {// An option used to indicate that the view does not resize. UIViewAutoresizingNone = 0, / / by expand or narrow view in the left margin direction to adjust the size UIViewAutoresizingFlexibleLeftMargin = 1 < < 0, / / by extending or narrow view width to resize UIViewAutoresizingFlexibleWidth = 1 < < 1, / / by expand or narrow view in the right margin direction to adjust the size UIViewAutoresizingFlexibleRightMargin = 1 < < 2, / / by expand or narrow view on top margin direction to adjust the size UIViewAutoresizingFlexibleTopMargin = 1 < < 3, / / by larger or smaller view to adjust the height of size UIViewAutoresizingFlexibleHeight = 1 < < 4, / / by expand or narrow view on bottom margin direction to adjust the size UIViewAutoresizingFlexibleBottomMargin = 1 < < 5};Copy the code

@property(nullable, nonatomic,copy) NSArray<__kindof UIGestureRecognizer *> *gestureRecognizers API_AVAILABLE(ios(3.2));

Property Description: The gesture recognizer object currently attached to the view. Each object is an instance of a subclass of the abstract base class UIGestureRecognitizer. The default value for this property is zero. If you add a gesture recognizer and then remove it, the value of this property is an empty array.

@property(nullable, nonatomic,copy) NSArray<__kindof UIGestureRecognizer *> *gestureRecognizers API_AVAILABLE(ios(3.2));
Copy the code
Commonly used functions

– (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;

Returns the farthest descendant of the receiver (including itself) containing the specified point in the view hierarchy. This method iterates through the view hierarchy by calling the pointInside:withEvent: method of each child view to determine which child view should receive a touch event. If pointInside:withEvent: returns YES, the hierarchy of subviews is traversed until the foremost view containing the specified point is found. If the view does not contain this point, the branch of its view hierarchy is ignored. You rarely need to call this method yourself, but you can override it to hide touch events from subviews.

This method ignores filtering of view objects that hide, disable user interaction, or have an alpha level less than 0.01. This method does not consider the contents of the view when determining a click. Therefore, a view can be returned even if the specified point is in a transparent part of the view’s content.

Points outside the receiver boundary are never reported as clicks, even though they are actually in the receiver’s subview. This can happen if the clipsToBounds property of the current view is set to NO and the affected subviews are outside the bounds of the view.

Parameters:

Point: A point specified in the receiver’s local coordinate system (boundary).

Event: The event that warrants calling this method. If this method is called from outside the event handling code, you can specify nil.

Return value: View object, which is the most distant child of the current view and contains points. If the point is completely outside the receiver’s view hierarchy, nil is returned.

- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
Copy the code

– (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;

Function description: Returns a Boolean value indicating whether the receiver contains the specified point.

Parameters:

Point: a point in the receiver’s local coordinate system (boundary).

Event: The event that warrants calling this method. If this method is called from outside the event handling code, you can specify nil.

Return value: YES if the point is in range of the receiver; Otherwise, NO.

- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event; 
Copy the code

– (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;

Converts a point from the receiver’s coordinate system to the specified view’s coordinate system.

Parameters:

Point: A point specified in the receiver’s local coordinate system (boundary).

View: The view to which the coordinate system point is to be converted. If view is nil, this method converts to window base coordinates. Otherwise, the view and the receiver must belong to the same UIWindow object.

Return value: point converted to view coordinate system.

- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
Copy the code

Simple examples, such as making parts of a button that are outside the scope of the superview respond to clicks

@interface testView : UIView @property (nonatomic, strong)UIButton *testCodeButton; @end @implementation testView - (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if(self){ self.testCodeButton = [UIButton buttonWithType:UIButtonTypeCustom]; self.testCodeButton.backgroundColor = [UIColor blueColor]; Self. TestCodeButton. Alpha = 0.5; self.testCodeButton.titleLabel.font = [UIFont systemFontOfSize:15]; [the self testCodeButton setTitle: @ "test code" forState: UIControlStateNormal]; [self.testCodeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [self addSubview:self.testCodeButton]; [self.testCodeButton mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mas_top).offset(-35); make.centerX.equalTo(self); make.size.mas_equalTo(CGSizeMake(150, 55)); }]; } return self; } - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *view = [super hitTest:point withEvent:event]; if ([view isKindOfClass:[UIButton class]]) { return view; }else if (view == nil) {CGPoint newPoint = [self.testCodeButton convertPoint:point fromView:self]; / / determine whether touch point on the button if (CGRectContainsPoint (self. TestCodeButton. Bounds, newPoint)) {view = self. TestCodeButton; } } return view; } @end @interface TestCodeController () @property (nonatomic, strong) testView *tview; @end @implementation TestCodeController - (void)viewDidLoad { [super viewDidLoad]; The self. The navigationItem. Title = @ "test code controller"; self.tview = [[testView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMaxY(self.view.frame) / 2 - 150 / 2, 150, 150)]; self.tview.backgroundColor = [UIColor redColor]; [self.tview.testCodeButton addTarget:self action:@selector(testCode) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:self.tview]; Void testCode{YSUIntent *intent = [[YSUIntent alloc]initWithClassName:@" "]; intent.useNavigationToPush = YES; intent.method = OPEN_METHOD_POP; [self openIntent:intent]; } @endCopy the code

HitTest :(CGPoint) Point withEvent:(Nullable UIEvent *)event

HitTest (CGPoint) Point withEvent (Nullable UIEvent *)event

– (CGSize)sizeThatFits:(CGSize)size;

Function description: Asks the view to calculate and return the size that best fits the specified size. The default implementation of this method returns the existing size of the view. Subclasses can override this method to return custom values based on the desired layout of any subview. For example, a UISwitch object returns a fixed-size value that represents the standard size of a Switch view, while a UIImageView object returns the size of the image it is currently displaying. This method does not resize the receiver.

Parameters:

Size: The size by which the view should calculate its best fit size

Return value: New size suitable for the receiver’s subview.

- (CGSize)sizeThatFits:(CGSize)size;   
Copy the code

– (void)sizeToFit;

Resize the receiver view and move it to enclose its child views. Call this method if you want to resize the current view so that it uses the most appropriate amount of space. A particular UIKit view adjusts its size according to its own internal needs. In some cases, if a view does not have a superview, it may resize itself based on screen boundaries. Therefore, if you want a given view to resize itself to its parent view, you should add it to the parent view before calling this method.

This method should not be overridden. If you want to change the default size information for the view, override sizeThatFits: instead. The method performs any required calculations and returns them to the method, which then makes changes.

- (void)sizeToFit; 
Copy the code

Note: This method is usually used when using UILabel. Before using UILabel, you must assign a value to the label, otherwise the content will not be displayed. SizeThatFits calculates the optimal size but does not change its size. SizeToFit calculates the optimal size and changes its size.

UIView(UIViewHierarchy) – View hierarchy

Commonly used functions

– (void)removeFromSuperview;

Unlink the view from the parent view and its window and remove it from the response chain. If the view’s parent is not nil, the parent releases the view. Calling this method removes any constraints that point to the view to be deleted, or to any view in the subtree of the view to be deleted.

Note: Never call this method from a view’s drawRect: method.

- (void)removeFromSuperview;
Copy the code

For example, when dealing with bugs, when the page is refreshed, it looks like this:

The solution is to remove the subviews from the view before each refresh:

  1. MakeObjectsPerformSelector: simplifying the cyclic code, each element of an array of execution @ the selector (removeFromSuperview) specified removeFromSuperview method. The element’s type must have this method, otherwise an unrecognized selector sent to instance error occurs.

  2. RemoveFromSuperview: Removes the current view from its parent view.

[self.imgBackView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Copy the code
- (void)removeFromSuperview{ [self.imgBackView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull subView,  NSUInteger idx, BOOL * _Nonnull stop) { [subView removeFromSuperview]; }]; }Copy the code

After processing, refresh frequently here, like this:

– (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;

Inserts a subview at the specified index. This method establishes a strong reference to the view and sets its next responder as a sink, which is its new superview. A view can have only one parent view. If the view already has a parent that is not a sink (sink refers to the object calling the function), this method removes the previous parent before making the sink its new parent.

Parameters:

View: The view to insert. This value cannot be null.

Index: The index in the subview property array into which the view is to be inserted. The subview index starts at 0 and cannot be greater than the number of subviews.

- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
Copy the code

– (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;

Swaps subviews at the specified index. Each index represents the position of the corresponding view in the array in the subview property. The subview index starts at 0 and cannot be greater than the number of subviews. This method does not change the parent views of any of the views, but simply swaps their positions in the child view array.

Parameters:

Index1: Index of the first subview in the sink.

Index2: Index of the second subview in the sink.

- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;
Copy the code

For example, swapping two view hierarchies:

@interface TestCodeController () @property (nonatomic, strong) UIView *view1; @property (nonatomic, strong) UIView *view2; @end @implementation TestCodeController - (void)viewDidLoad { [super viewDidLoad]; The self. The navigationItem. Title = @ "test code controller"; self.view1 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMaxY(self.view.frame) / 2 - 150 / 2, 150, 150)]; self.view1.backgroundColor = [UIColor redColor]; [self.view addSubview:self.view1]; self.view2 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMaxY(self.view.frame) / 2 - 150 / 2, 150, 150)]; self.view2.backgroundColor = [UIColor greenColor]; [self.view addSubview:self.view2]; UIButton *testCodeButton = [UIButton buttonWithType:UIButtonTypeCustom]; testCodeButton.frame = CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 75 / 2, CGRectGetMaxY(self.view1.frame) + 20, 75, 30); testCodeButton.backgroundColor = [UIColor blueColor]; testCodeButton.titleLabel.font = [UIFont systemFontOfSize:15]; [testCodeButton setTitle: @ "test code" forState: UIControlStateNormal]; [testCodeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [testCodeButton addTarget:self action:@selector(testCode) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:testCodeButton]; } / / / test button click - (void) testCode {[self testexchangeSubviewAtIndex: self. The view1 andView: self. The view2]; } / / / exchange view hierarchy - (void) testexchangeSubviewAtIndex: (UIView *) the view1 andView view2: (UIView *) {NSInteger index1 = 0; NSInteger index2 = 0; for (int i = 0; i < self.view.subviews.count; i++) { if([self.view.subviews[i] isEqual:view1]){ index1 = I; }else if([self.view.subviews[i] isEqual:view2]){ index2 = I; } } if(index1 ! = index2){ [self.view exchangeSubviewAtIndex:index1 withSubviewAtIndex:index2]; }}Copy the code

The effect is as follows:

– (void)addSubview:(UIView *)view;

Function description: Adds the view to the end of the list of subviews of the receiver. This method establishes a strong reference to the view and sets its next responder as a sink, which is its new superview. A view can have only one parent view. If the view already has a parent that is not the recipient, this method removes the previous parent before making the receiver its new parent.

Parameters:

View: The view to add. When added, this view will appear on top of any other child views.

- (void)addSubview:(UIView *)view;
Copy the code

– (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;

Inserts a view below another view in the view hierarchy. This method establishes a strong reference to the view and sets its next responder as a sink, which is its new superview. A view can have only one parent view. If the view already has a parent that is not a receiver, this method removes the previous parent before making the receiver its new parent.

Parameters:

View: The view to be inserted under another view. If it is not a sibling of the siblingSubview, it is removed from its superView.

SiblingSubview: Inserts sibling view above view.

- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
Copy the code

For example, insert a view under another view in the view hierarchy:

#import "TestCodeController.h" @interface TestCodeController () @property (nonatomic, strong) UIView *view1; @property (nonatomic, strong) UIView *view2; @property (nonatomic, strong) UIView *view3; @end @implementation TestCodeController - (void)viewDidLoad { [super viewDidLoad]; The self. The navigationItem. Title = @ "test code controller"; self.view1 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMaxY(self.view.frame) / 2 - 150 / 2, 150, 150)]; self.view1.backgroundColor = [UIColor redColor]; [self.view addSubview:self.view1]; self.view2 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMinY(self.view1.frame) + 30, 150, 150)]; self.view2.backgroundColor = [UIColor greenColor]; [self.view addSubview:self.view2]; self.view3 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMinY(self.view1.frame) + 15, 150, 150)]; self.view3.backgroundColor = [UIColor yellowColor]; UIButton *testCodeButton = [UIButton buttonWithType:UIButtonTypeCustom]; testCodeButton.frame = CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 75 / 2, CGRectGetMaxY(self.view1.frame) + 40, 75, 30); testCodeButton.backgroundColor = [UIColor blueColor]; testCodeButton.titleLabel.font = [UIFont systemFontOfSize:15]; [testCodeButton setTitle: @ "test code" forState: UIControlStateNormal]; [testCodeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [testCodeButton addTarget:self action:@selector(testCode) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:testCodeButton]; } / / / test button click - (void) testCode {[self testInsertSubview: self. View3 belowSubview: self. The view2]; } /// insert a view below another view in the view hierarchy - (void)testInsertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview{[self.view insertSubview:view belowSubview:siblingSubview]; }Copy the code

The effect is as follows:

– (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;

Inserts a view above another view in a view hierarchy. This method establishes a strong reference to the view and sets its next responder as a receiver, which is its new parent view. A view can have only one parent view. If the view already has a parent that is not a receiver, this method removes the previous parent before making the receiver its new parent.

Parameters:

View: The view to insert. If it is not a sibling of the siblingSubview, it is removed from its superView.

SiblingSubview: Sibling view under the inserted view.

- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
Copy the code

– (void)bringSubviewToFront:(UIView *)view;

Moves the specified subview to display at the top of its sibling view. This method moves the specified view to the end of the view array in the “SubViews” property.

Parameters:

View: To move to the previous subview.

- (void)bringSubviewToFront:(UIView *)view;
Copy the code

For example, move the specified subview so that it appears at the top of its sibling view:

#import "TestCodeController.h" @interface TestCodeController () @property (nonatomic, strong) UIView *view1; @property (nonatomic, strong) UIView *view2; @property (nonatomic, strong) UIView *view3; @end @implementation TestCodeController - (void)viewDidLoad { [super viewDidLoad]; The self. The navigationItem. Title = @ "test code controller"; self.view1 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMaxY(self.view.frame) / 2 - 150 / 2, 150, 150)]; self.view1.backgroundColor = [UIColor redColor]; [self.view addSubview:self.view1]; self.view2 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMinY(self.view1.frame) + 30, 150, 150)]; self.view2.backgroundColor = [UIColor greenColor]; [self.view addSubview:self.view2]; self.view3 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMinY(self.view1.frame) + 15, 150, 150)]; self.view3.backgroundColor = [UIColor yellowColor]; [self.view addSubview:self.view3]; UIButton *testCodeButton = [UIButton buttonWithType:UIButtonTypeCustom]; testCodeButton.frame = CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 75 / 2, CGRectGetMaxY(self.view1.frame) + 40, 75, 30); testCodeButton.backgroundColor = [UIColor blueColor]; testCodeButton.titleLabel.font = [UIFont systemFontOfSize:15]; [testCodeButton setTitle: @ "test code" forState: UIControlStateNormal]; [testCodeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [testCodeButton addTarget:self action:@selector(testCode) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:testCodeButton]; } / / / test button click - (void) testCode {[self testBringSubviewToFront: self. The view1]; } /// Move the specified subview to the top of its sibling - (void)testBringSubviewToFront:(UIView *)view{[self.view bringSubviewToFront:view]; }Copy the code

The effect is as follows:

– (void)sendSubviewToBack:(UIView *)view;

Moves the specified subview to appear behind its sibling view. This method moves the specified view to the beginning of the view array in the “SubViews” property.

Parameters:

View: The subview to move to.

- (void)sendSubviewToBack:(UIView *)view;
Copy the code

– (void)didAddSubview:(UIView *)subview;

Tells the view that a child view has been added. The default implementation of this method does nothing. Subclasses can override it to do something else when they add a child view. This method is called when a child view is added using any associated view methods.

Parameters:

Subview: A view added as a subview.

- (void)didAddSubview:(UIView *)subview;
Copy the code

Such as:

@interface TestView : UIView @property (nonatomic, assign) NSInteger number; @end @implementation TestView - (void)didAddSubview:(UIView *)subview{ [super didAddSubview:subview]; self.number += 1; NSLog(@" add %ld sub view ",(long)self.number); } @end @interface TestCodeController () @property (nonatomic, strong) TestView *contentView; @property (nonatomic, strong) UIView *view1; @property (nonatomic, strong) UIView *view2; @property (nonatomic, strong) UIView *view3; @end @implementation TestCodeController - (void)viewDidLoad { [super viewDidLoad]; The self. The navigationItem. Title = @ "test code controller"; self.contentView = [[TestView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame))]; [self.view addSubview:self.contentView]; self.view1 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMaxY(self.view.frame) / 2 - 150 / 2, 150, 150)]; self.view1.backgroundColor = [UIColor redColor]; [self.contentView addSubview:self.view1]; self.view2 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMinY(self.view1.frame) + 30, 150, 150)]; self.view2.backgroundColor = [UIColor greenColor]; [self.contentView addSubview:self.view2]; self.view3 = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 150 / 2, CGRectGetMinY(self.view1.frame) + 15, 150, 150)]; self.view3.backgroundColor = [UIColor yellowColor]; [self.contentView addSubview:self.view3]; UIButton *testCodeButton = [UIButton buttonWithType:UIButtonTypeCustom]; testCodeButton.frame = CGRectMake(CGRectGetMaxX(self.view.frame) / 2 - 75 / 2, CGRectGetMaxY(self.view1.frame) + 40, 75, 30); testCodeButton.backgroundColor = [UIColor blueColor]; testCodeButton.titleLabel.font = [UIFont systemFontOfSize:15]; [testCodeButton setTitle: @ "test code" forState: UIControlStateNormal]; [testCodeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [testCodeButton addTarget:self action:@selector(testCode) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:testCodeButton]; }Copy the code

The output is shown as follows:

– (void)willRemoveSubview:(UIView *)subview;

Function description: Tells a view that its subview is about to be deleted. The default implementation of this method does nothing. Subclasses can override it to do something else when deleting a subview. This method is called when the parent view of a child view changes or the child view is completely removed from the view hierarchy.

Parameters:

Subview: Subview to be deleted.

- (void)willRemoveSubview:(UIView *)subview;
Copy the code

– (void)layoutSubviews;

Function description: This method is called when adjusting the position of a subview inside a class. It does nothing by default and needs to be overridden by subclasses. LayoutSubviews are not triggered by initialization, but when a frame that is not CGRectZero is set and added to the superview, it is triggered by [super layoutSubviews] at the end of the implementation. This method should not be called directly. If you want to force a layout update, call the setNeedsLayout method before the next graphics update. To update the view’s layout immediately, call the layoutIfNeeded method.

1. Call [self setNeedsLayout] directly; 2. AddSubview. 3. When the view size changes, the frame value changes before and after setting. 4. When sliding UIScrollView. 5. Rotating Screen triggers the layoutSubviews event on the parent UIView

- (void)layoutSubviews;
Copy the code

In layoutSubviews, you can also add a CALayer object to the cell of the table view for layout operations, such as adding a dividing line or gradient layer. Here is a simple example of adding a dividing line, such as adding a similar dividing line:

If you add a CALayer to the cell initialization of the table view, the width obtained by self.contentView.frame is usually inaccurate.

Add CALayer code snippet to cell initialization function:

Self. separatorLineLayer = [[CALayer alloc] init]; NSLog(@"%f",CGRectGetHeight(self.contentView.frame)); NSLog(@"%f",CGRectGetWidth(self.contentView.frame)); Self. SeparatorLineLayer. Frame = CGRectMake (0, CGRectGetHeight (self. The contentView. The frame) - 0.5, CGRectGetWidth (self. The contentView. The frame), 0.6); [self.contentView.layer addSublayer:_separatorLineLayer]; self.separatorLineLayer.backgroundColor = [UIColor grayColor].CGColor;Copy the code

The printed result is:

The view style is:

In order to more accurately layout the CALayer object in the cell, the cell initialization function can initialize the CALayer object as a dividing line, but do not set the frame, and the frame is laid out in layoutSubviews, so that a more accurate layout can be obtained.

Add CALayer code snippet to cell initialization function:

Self. separatorLineLayer = [[CALayer alloc] init]; [self.contentView.layer addSublayer:_separatorLineLayer]; self.separatorLineLayer.backgroundColor = [UIColor grayColor].CGColor;Copy the code

Set the frame snippet in layoutSubviews:

Void layoutSubviews {[super layoutSubviews]; NSLog(@"%f",CGRectGetHeight(self.contentView.frame)); NSLog(@"%f",CGRectGetWidth(self.contentView.frame)); Self. SeparatorLineLayer. Frame = CGRectMake (0, CGRectGetHeight (self. The contentView. The frame) - 0.5, CGRectGetWidth (self. The contentView. The frame), 0.6); }Copy the code

The printed result is:

The view style is:

– (void)setNeedsLayout;

Function description: Invalidates the current layout of the receiver and triggers a layout update in the next update cycle. Call this method on the main thread of your application if you want to adjust the layout of a view’s subviews. This method logs the request and returns it immediately. Because this method does not force an immediate update but waits for the next update cycle, it can be used to invalidate the layout of multiple views before updating any view. This behavior allows you to consolidate all layout updates into one update cycle, which is usually better for performance.

Set the layout and tell the system that the view needs to be updated. This method will return immediately, but the view will be updated in the next update cycle, calling the view’s layoutSubviews.

- (void)setNeedsLayout;
Copy the code

Such as:

- (void)setBgColor:(UIColor *)bgColor {
    _bgColor = bgColor;
    
    self.backgroundColor = bgColor;
    [self setNeedsLayout];
}
Copy the code

– (void)layoutIfNeeded;

Function description: If the layout update is suspended, the subview is immediately laid out. Use this method to force the view to update its layout immediately. With automatic layout, the layout engine updates the position of the view as needed to meet changes in constraints. Using the view receiving the message as the root view, this method lays out the view subtree from the root. If the layout is not updated, the method exits without modifying the layout or calling any layout-related callbacks.

LayoutIfNeeded does not necessarily trigger layoutSubviews of a view. The system detects the triggering conditions of layoutSubviews. If the conditions are met, layoutSubviews will be triggered immediately without waiting for the next update cycle. However, layoutSubviews will not be triggered if they do not meet the triggering conditions.

- (void)layoutIfNeeded;
Copy the code

For example: changing the layout of the view animation block using the navigation code will trigger the animation only after layoutIfNeeded is called:

[UIView animateWithDuration:1 animations:^{
    [self.customSelectRecurrenceView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.view.mas_bottom).offset(-YSLCommonPadding * 2);
        make.centerX.equalTo(self.view);
        make.size.mas_equalTo(CGSizeMake(SCREEN_WIDTH - 20, 540));
    }];
    [self.view layoutIfNeeded];
 } completion:^(BOOL finished) {
    self.repetitionModeTableView.hidden = YES;
 }];
Copy the code

UIView(UIViewRendering) – View rendering

Commonly used attributes

@property(nonatomic) BOOL clipsToBounds;

Property description: A Boolean value that determines whether a subview is bounded within a view’s boundaries. Setting this value to “YES” causes the subview to be clipped to the receiver boundary. If set to “NO”, the subview of the frame beyond the receiver’s visible boundary is not clipped. The default value is NO.

@property(nonatomic)                 BOOL              clipsToBounds; 
Copy the code

@property(nullable, nonatomic,copy) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;

Property description: The background color of the view. Changes to this property can be animated. The default value is nil, which produces a transparent background color.

@property(nullable, nonatomic,copy)            UIColor          *backgroundColor UI_APPEARANCE_SELECTOR;
Copy the code

@property(nonatomic) CGFloat alpha;

Property description: Alpha value of the view. The value of this property is a floating point number between 0.0 and 1.0, where 0.0 means completely transparent and 1.0 means completely opaque. Changing the value of this property updates only the alpha value of the current view. However, the transparency given by this alpha value affects everything in the view, including its children. For example, a child view with alpha 1.0 embedded in a parent view with alpha 0.5 will appear on the screen as if it had alpha 0.5 as well. Changes to this property can be animated.

@property(nonatomic)                 CGFloat           alpha; 
Copy the code

@property(nonatomic,getter=isOpaque) BOOL opaque;

Property description: Boolean value that determines whether a view is opaque. This property gives the drawing system an indication of how the view should be handled. If set to YES, the drawing system treats the view as completely opaque, which allows the drawing system to optimize some drawing operations and improve performance. If set to NO, the drawing system will normally combine the view with other content. The default value for this property is YES.

Opaque views should fill their boundaries with completely opaque content — that is, the content should have an alpha value of 1.0. If the view is opaque, or does not fill its boundaries, or contains content that is completely or partially transparent, the results are unpredictable. If the view is fully or partially transparent, the value of this property should always be set to NO.

Just set a value for the Opaque property in a UIView subclass that draws its own content using the drawRect: method. Opaque properties do not work in system-provided classes such as UIButton, UILabel, UITableViewCell, and so on.

@property(nonatomic,getter=isOpaque) BOOL              opaque;
Copy the code

@property(nonatomic) BOOL clearsContextBeforeDrawing;

Property description: A Boolean value that determines whether to automatically clear view boundaries before drawing. When set to YES, the draw buffer is automatically cleared to transparent black before the drawRect: method is called. This behavior ensures that no visual blemishes are left when the view content is redrawn. If the opaque property of the view is also set to YES, the view’s backgroundColor property cannot be nil, otherwise a drawing error may occur. The default value for this property is YES.

If you set the value of this property to NO, you are responsible for ensuring that the contents of the view are drawn correctly in the drawRect: method. Setting this property to “No” can improve performance if the graphics code has been heavily optimized, especially when scrolling through views where only part of the view may need to be redrawn.

@property(nonatomic)                 BOOL              clearsContextBeforeDrawing;
Copy the code

@property(nonatomic,getter=isHidden) BOOL hidden;

Property description: Boolean value that determines whether the view is hidden. Setting the value of this property to “YES” will hide the receiver, and setting it to “NO” will show the receiver. The default value is NO.

The hidden view disappears from its window and does not receive input events. However, it remains in the list of subviews of its SuperView and participates in automatic resizing as usual. The effect of hiding views that contain subviews is to hide those subviews and any view descendants that they may have. The effect is implicit and does not alter the hidden state of the recipient’s offspring.

Hiding the view as the window’s current first responder causes the view’s next valid key view to become the new first responder.

The value of this property reflects only the state of the receiver, not the state of the receiver ancestor in the view hierarchy. Therefore, this attribute can be NO, but if an ancestor is hidden, the receiver may still be hidden.

@property(nonatomic,getter=isHidden) BOOL              hidden; 
Copy the code

@property(nonatomic) UIViewContentMode contentMode;

Attribute description: Flags used to determine how a view lays out its content when its boundaries change. The content mode specifies how to adjust the cached view layer bitmap when the view’s boundaries change. This property is typically used to implement resizable controls. Instead of redrawing the contents of the view each time, you can use this property to specify that you want to scale the contents (with or without distortion) or fix them to a specific location on the view.

@property(nonatomic)                 UIViewContentMode contentMode; 
Copy the code

Enumeration of UIViewContentMode

Typedef NS_ENUM(NSInteger, UIViewContentMode) {// The option to scale content to fit its own size by changing the aspect ratio of content as needed. / / UIImageView, when using tensile padding to the whole image UIImageView UIViewContentModeScaleToFill (images may be deformation), / / by keeping aspect ratio zoom content to adapt to the size of the view options. Any remaining area of the view boundary is transparent. / / UIImageView, when using image stretching until fully display inside the UIImageView (image) will not deformation, but may be long or wide one direction space UIViewContentModeScaleAspectFit, / / zoom content to fill the size of the view options. Parts of the content may be clipped to fill in the boundaries of the view. // When UIImageView is used, the image is stretched until it is fully displayed in the UIImageView. But may be over the boundary of the UIImageView and redundancy UIViewContentModeScaleAspectFill, / / when the boundary change by calling setNeedsDisplay method to display the view options. UIViewContentModeRedraw, // The option to center the content at the edge of the view, keeping the ratio constant. UIViewContentModeCenter, // The option to center content at the top of the view boundary. UIViewContentModeTop, // The option to centralize content at the bottom of the view boundary UIViewContentModeBottom, // the option to align content on the left side of the view. UIViewContentModeLeft, // The option to align content on the right side of the view. UIViewContentModeRight, // The option to align content in the upper left corner of the view. UIViewContentModeTopLeft, / / on the top right corner view alignment content option. UIViewContentModeTopRight, / / align left corner content view options. UIViewContentModeBottomLeft, / / align option to view the content and the bottom right hand corner. UIViewContentModeBottomRight, };Copy the code
Commonly used functions

– (void)setNeedsDisplay;

Marks the receiver’s entire bounding rectangle as needing to be redrawn. You can use this method or setNeedsDisplayInRect: To notify the system that the contents of the view need to be redrawn. This method logs the request and returns it immediately. The view is not actually redrawn until the next drawing cycle, when all invalid views are updated.

This method has no effect if your view is supported by a CAEAGLLayer object. It is only used for views that use native drawing technologies such as UIKit and Core Graphics to render content. You should use this method to request that the view be redrawn only when its content or appearance changes. If you just change the geometry of the view, you will not normally redraw the view. Instead, its existing content is adjusted based on the value in the view’s contentMode property. Redisplaying existing content improves performance by avoiding redrawing content

Similar to the setNeedsLayout method. This method, when called, automatically calls the drawRect method. The drawRect method is mainly used to draw diagrams. So, when you need to refresh the layout, use the setNeedsLayout method; When you need to redraw, call the setNeedsDisplay method.

- (void)setNeedsDisplay;
Copy the code

Such as:

- (void)setFillColor:(UIColor *)fillColor {
    if (fillColor) {
        _fillColor = fillColor;
    } else {
        _fillColor = [UIColor whiteColor];
    }
    [self setNeedsDisplay];
}
Copy the code

– (void)drawRect:(CGRect)rect;

Property description: This method does nothing during the view loading process by default. When subclasses draw the view content, they can add the drawn code to this method. If the Rect size is not set at UIView initialization, drawRect will not be called automatically. If Rect is set, setNeedsDisplay can be invoked directly. If the view sets its content in other ways, you do not need to override this method. For example, if the view displays only the background color, or if the view sets its content directly with the base layer object, you do not need to override this method.

When this method is called, UIKit has configured an appropriate drawing environment for the view and can simply call any drawing methods and functions needed to render the content. Specifically, UIKit creates and configures the graphics context, and adjusts the transformation of that context so that its origin matches the origin of the view’s border rectangle. Can use UIGraphicsGetCurrentContext function retrieves a reference to graphics context, but don’t build strong reference of the graphics context, because it can be in the drawRect: method of calls between changes.

This method is called when the view is first displayed or when an event invalidates the visible part of the view. You should not call this method directly yourself. To invalidate a part of a view, causing it to be redrawn, call the setNeedsDisplay or setNeedsDisplayInRect: methods instead.

Parameters:

Rect: Part of the view boundary that needs to be updated. The first time a view is drawn, this rectangle is usually the entire visible boundary of the view. However, during subsequent drawing operations, the rectangle may specify only a portion of the view.

- (void)drawRect:(CGRect)rect;
Copy the code

UIView (UIViewAnimationWithBlocks) – view the animation code block

Commonly used functions

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void)) API_AVAILABLE(ios(4.0));

Function description: Animates changes to one or more views with the specified duration. This method USES UIViewAnimationOptionCurveEaseInOut and UIViewAnimationOptionTransitionNone animation options immediately perform the specified animation.

During animation, user interaction with the view that is being animated is temporarily disabled. (Prior to iOS 5, user interaction was disabled for the entire app.)

Parameters:

Duration: Total duration of an animation, in seconds. If a negative value or 0 is specified, the change is made without setting the animation.

Animations: Block objects that contain changes to be submitted to the view. This is where you programmatically change any animatable properties of a view in the view hierarchy. This block takes no arguments and has no return value. This parameter cannot be NULL.

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void)) API_AVAILABLE(ios(4.0));Copy the code

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable) (BOOL finished)) completion API_AVAILABLE (ios (4.0));

Function description: Animates changes to one or more views with the specified duration and completion handler. This method USES UIViewAnimationOptionCurveEaseInOut and UIViewAnimationOptionTransitionNone animation options immediately perform the specified animation.

During animation, user interaction with the view that is being animated is temporarily disabled. (Prior to iOS 5, user interaction was disabled for the entire app.)

Parameters:

Duration: Total duration of an animation, in seconds. If a negative value or 0 is specified, the change is made without setting the animation.

Animations: Block objects that contain changes to be submitted to the view. This is where you programmatically change any animatable properties of a view in the view hierarchy. This block takes no arguments and has no return value. This parameter cannot be NULL.

Completion: The block object executed at the end of the animation sequence. This block has no return value, only a Boolean parameter indicating whether the animation has completed before the completion handler is called. If the duration of the animation is 0, the block is executed at the beginning of the next run cycle. This parameter can be NULL.

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable) (BOOL finished)) completion API_AVAILABLE (ios (4.0));Copy the code

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion API_AVAILABLE (ios (4.0));

Function description: Animates changes to one or more views using the specified duration, delay, options, and completion handlers.

This method starts a set of animations to be executed on the view. The block object in the Animations parameter contains code to animate one or more view properties.

During animation, user interaction with the view that is being animated is temporarily disabled. (Prior to iOS 5, user interaction was disabled for the entire app.) If you want users to be able to interact with the view, please include UIViewAnimationOptionAllowUserInteraction constants in the options parameter.

Parameters:

Duration: Total duration of an animation, in seconds. If a negative value or 0 is specified, the change is made without setting the animation.

Delay: The amount of time (in seconds) to wait before the animation starts. Specify a value of 0 to start animation immediately.

Options: An option mask that indicates how to perform the animation.

Animations: Block objects that contain changes to be submitted to the view. This is where you programmatically change any animatable properties of a view in the view hierarchy. This block takes no arguments and has no return value. This parameter cannot be NULL.

Completion: The block object executed at the end of the animation sequence. This block has no return value, only a Boolean parameter indicating whether the animation has completed before the completion handler is called. If the duration of the animation is 0, the block is executed at the beginning of the next run cycle. This parameter can be null.

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options  animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion API_AVAILABLE (ios (4.0));Copy the code

Simple exercise code snippet:

- (void)testAnimationBlock{// create a test animationLabel UILabel *animationLabel = [[UILabel alloc]initWithFrame:CGRectMake(20, CGRectGetMaxY(self.view.frame) / 2, 200, 20)]; animationLabel.textColor = [UIColor whiteColor]; animationLabel.backgroundColor = [UIColor blueColor]; Animationlabel. text = @" I showed up ready to run "; animationLabel.textAlignment = NSTextAlignmentCenter; AnimationLabel. Layer. The cornerRadius = 8.0; animationLabel.layer.masksToBounds = YES; AnimationLabel. Alpha = 0.0; [self.view addSubview:animationLabel]; [UIView animateWithDuration: delay 5.0:10.0 options: UIViewAnimationOptionCurveEaseInOut animations: ^ { AnimationLabel. Alpha = 1.0;} completion:^(BOOL finished) {[UIView animateWithDuration:2.0 animations:^{CGRect newAnimationLabelFrame = animationLabel.frame; newAnimationLabelFrame.origin.x = CGRectGetMaxX(self.view.frame) - 200 - } completion:^(BOOL finished) {animationLabel.text = @" I'm going to run here "; }];}]; }Copy the code

The animation effect is shown in the figure below:

UIView (UIConstraintBasedLayoutLayering) – the layout of the stratification based on constraints

Commonly used attributes

Property (nonatomic, readOnly) CGSize intrinsicContentSize API_AVAILABLE(ios(6.0));

Attribute description: Receives the natural size of the view, considering only the attributes of the view itself. Custom views usually show things that the layout system doesn’t know about. By setting this property, a custom view can communicate its desired size to the layout system based on its content. This intrinsic size must be independent of the content frame because, for example, the width of the change cannot be dynamically passed to the layout system based on the height of the change. If a custom view does not have an internal size for a given dimension, you can use UIViewNoIntrinsicMetric for that dimension.

Property (nonatomic, readOnly) CGSize intrinsicContentSize API_AVAILABLE(ios(6.0));Copy the code

For example, when customizing a navigation view, add a button that does not respond to a click:

It is possible to overwrite the intrinsicContentSize property in the customizable view.h file and set the value of the intrinsicContentSize property when instantiating the customizable view, for example:

@interface YSCNavigationItemTitleView : UIView @property(nonatomic, assign) CGSize intrinsicContentSize; // Override intrinsicContentSize attribute @Property (nonatomic, strong) UILabel *titleLabel; // title tag @Property (nonatomic, strong) UIButton *orderTypeSelectionButton; @property(nonatomic, strong) UIButton *labelMakeButton; // Title tag mask button @endCopy the code
- (void) createNavigationTitleView text: (nsstrings *) {/ / initializes the order summary of custom title YSCNavigationItemTitleView view *navigationItemTitleView = [[YSCNavigationItemTitleView alloc]initWithFrame:CGRectZero]; / / computed text rectangle CGRect the rect = [navigationItemTitleView. TitleLabel. Text boundingRectWithSize: CGSizeMake (CGFLOAT_MAX, [YSCUiUtils singleCharactorSizeWithFont:[YSCUiUtils fontOne]].height) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:20]} context:nil]; / / set the custom title view size of the order summary navigationItemTitleView. IntrinsicContentSize = CGSizeMake (the rect. Size. Width, [YSCUiUtils singleCharactorSizeWithFont:[YSCUiUtils fontOne]].height); }Copy the code

UIView (UIConstraintBasedLayoutCoreMethods) – the core layout method based on constraint

Commonly used functions

– (void) updateConstraints API_AVAILABLE NS_REQUIRES_SUPER (ios (6.0));

Function description: The main function is to update the constraints of the view, and will call the method of all its subviews to update the constraints. Custom views should override this method to set the update their own constraints, and then call setNeedsUpdateConstraints tag constraints need to be updated. Before making a layout, the system calls updateConstraints. Call [super updateConstraints] at the end of your implementation.

Note: It is almost always cleaner and easier to update constraints immediately after an affecting change. For example, if you want to respond to the button click change constraint, make the change directly in the button action method.

This method should be overridden only if the in-place change constraint is too slow or if the view is generating a large number of redundant changes. We need to plan change, please call setNeedsUpdateConstraints to the view. The system then calls the implementation of updateConstraint before the layout occurs. You can verify that all necessary constraints on your content are in place while the attributes of your custom view are unchanged.

The implementation must be as efficient as possible. Do not deactivate all constraints and then reactivate the required constraints. Instead, the application must have some way of keeping track of constraints and validating them during each update. Change only the items that need to be changed. During each update, you must ensure that you have appropriate constraints on the current state of the application.

Don’t call setNeedsUpdateConstraints in implementation. Call setNeedsUpdateConstraints will schedule another update traversal, create a feedback loop. Call [Super updateConstraints] as the final step in your implementation.

- (void) updateConstraints API_AVAILABLE NS_REQUIRES_SUPER (ios (6.0));Copy the code

IOS View layout method

- (void)layoutSubviews;
- (void)setNeedsLayout;
- (void)setNeedsDisplay;
- (void)layoutIfNeeded;
- (void)drawRect:(CGRect)rect;
- (CGSize)sizeThatFits:(CGSize)size;
- (void)sizeToFit;
- (void)updateConstraints;
- (void)setNeedsUpdateConstraints; 
Copy the code

updateViewConstraints

– (void) updateViewConstraints API_AVAILABLE (ios (6.0));

Function description: UpdateViewConstraints is called when the view controller’s view needs to update its constraints. The appearance of updateViewConstraints makes it easier for the viewController to override the view of the controller. When updateConstraints of the view is called, If the view has a Controller, the updateViewConstraints of that controller will be called. You call [super updateViewConstraints] at the end of the implementation.

- (void) updateViewConstraints API_AVAILABLE (ios (6.0));Copy the code