Reproduced from: http://www.cnblogs.com/YouXianMing/p/3897543.html
From Baidu search for the use of layoutsubviews, the following is the result of the search, of course, the author will be verified.
1. Init initialization does not trigger Layoutsubviews
2, Addsubview will trigger Layoutsubviews
3, set the view frame will trigger layoutsubviews, of course, the premise is the value of the frame set before and after the change
4, rolling a uiscrollview will trigger layoutsubviews
5, rotate screen will trigger the Layoutsubviews event on the parent UIView
6, change a uiview size will also trigger the parent UIView on the Layoutsubviews event
Before beginning the verification, let's see what layoutsubviews is:
Lays out subviews.
The default implementation of this method does no on IOS 5.1 and earlier. Otherwise, the default implementation uses any constraints your have set to determine the size and position of any subviews .
In iOS5.1 or earlier versions, this method did nothing. The default implementation of this method is to use parameters to set the size and position of the subviews.
Subclasses can override this method as needed to perform more precise layout of their. You should override this method is only if the autoresizing and constraint-based behaviors of the The Subviews does not offer the B Ehavior you want. You can use your implementation to set the frame rectangles of your subviews directly.
If you need a more precise layout, you can override this method in subclasses. Only in the following cases: The automatic layout does not reach the effect you want to rewrite this method. You can set the subviews size directly.
You are not should to call this method directly. If you are want to force a layout update, call the Setneedslayout method instead to does so prior to the next drawing update. If you are want to update the layout of your views immediately, call the Layoutifneeded method.
You can't call this method directly. If you need to force layout refresh, call Setneedslayout instead. If you want to refresh your view immediately, call layoutifneeded
The following is probably summed up:
You do not call the method directly layoutsubviews, if you want to refresh, please call setneedslayout or layoutifneeded
OK, start validation:)
The following classes are now available to inherit to UIView:
// TestView.h
// layoutsubviews//// Copyright (c) 2014 y.x. All rights reserved.
#import <UIKit/UIKit.h>
@interface testview:uiview
@end
// testview.m
// layoutsubviews//// Copyright (c) 2014 y.x. All rights reserved.
#import "TestView.h"
@implementation TestView
-(ID) initWithFrame: (CGRect) frame
{
self = [Super Initwithframe:frame];
if (self)
{
NSLog (@ "initwithframe:%@", Nsstringfromcgrect (frame));
}
return self;
}
-(void) layoutsubviews
{
NSLog (@ "Layoutsubviews%@", self);
[Super Layoutsubviews];
}
@end
Test code:
ROOTVIEWCONTROLLER.M//Layoutsubviews////Copyright (c) 2014 y.x.
All rights reserved. #import "RootViewController.h" #import "TestView.h" @interface Rootviewcontroller () @property (nonatomic, Strong) N
Stimer *timer;
@property (nonatomic, strong) TestView *largeview;
@property (nonatomic, strong) TestView *smallview;
@end @implementation Rootviewcontroller-(void) viewdidload {[Super viewdidload]; 1. Init initialization does not trigger layoutsubviews [correct]//2, addsubview triggers layoutsubviews [not completely correct, when frame 0 o'clock is not triggered]//3, setting the view frame triggers the Lay
Outsubviews, of course, the premise is that the value of the frame changed before and after the change [correct]//[self test_1];
[Self test_2];
[Self test_3];
4, scrolling a uiscrollview will trigger layoutsubviews[error, without scrolling will trigger]//[self test_4];
5. Changing the size of a uiview also triggers the Layoutsubviews event on the parent UIView [self test_5]; }-(void) test_1 {/* Explanation: Go initwithframe: Method, but have frame value {{0, 0}, {0, 0}}, do not need to draw anything, so even if you add test, there is no need to draw It also verifies that addsubview triggers layoutsubviews is wrong and triggers only when the added view has a size LayoutsubviewS */TestView *test = [TestView new];
[Self.view Addsubview:test];
}-(void) test_2 {TestView *test = [TestView new];
Test.frame = CGRectMake (0, 0, 100, 100);
[Self.view Addsubview:test]; }-(void) Test_3 {/* Interpretation: Layoutsubviews This method itself cannot be invoked, is the method that is executed when the parent class is added * * TestView *test = [TestView new]
;
Test.frame = CGRectMake (0, 0, 50, 50);
UIView *showview = [[UIView alloc] Initwithframe:cgrectmake (0, 0, 50, 50)];
[Test Addsubview:showview];
}-(void) Test_4 {cgrect rect = self.view.bounds;
CGFloat height = rect.size.height;
CGFloat width = rect.size.width;
Uiscrollview *rootscroll = [[Uiscrollview alloc] initWithFrame:self.view.bounds];
Nsarray *data = @[@ "", @ "", @ "", @ ""]; [Data enumerateobjectsusingblock:^ (ID obj, Nsuinteger idx, BOOL *stop) {TestView *tmp = [[TestView alloc] Initwithframe:cgrectmake (width*idx, 0, Widt
h, height)];
[Rootscroll addsubview:tmp];
}]; Rootscroll.contEntsize = Cgsizemake (Width * data.count, height);
[Self.view Addsubview:rootscroll];
}-(void) test_5 {_timer = [Nstimer scheduledtimerwithtimeinterval:1.f target:self
Selector: @selector (timerevent:) Userinfo:nil Repeats:yes];
_largeview = [[TestView alloc] initWithFrame:self.view.bounds];
[Self.view Addsubview:_largeview];
_smallview = [[TestView alloc] Initwithframe:cgrectmake (0, 0, 100, 100)];
[_largeview Addsubview:_smallview]; }-(void) TimerEvent: (ID) Sender {_smallview.frame = CGRectMake (Arc4random ()%100 +, Arc4random ()%1
+, Arc4random ()%100 +, Arc4random ()%100 + 20);
NSLog (@ "_smallview%@", _smallview);
NSLog (@ "_smallview%@", _largeview); } @end
The conclusion after the test is this:
1. A view is not able to call Layoutsubviews itself, if you want to call, you need to call setneedslayout or layoutifneeded
2. If the frame value of view is 0, even if it is added yes will not call Layoutsubviews