从加载Controller到View显示,autoLayout是改变自己的frame去自适应的

首先,当你app运行起来时,会有个UIWindowScene的类,他的_windowSceneDelegate会返回一个类似AppDelegate的类的对象(是这个类->SceneDelegate),调用它的window方法,判断当前window是否存在,不存在,就会根据UIWindowScene类下的screen的大小创建一个window.存在就会调用_resizeWindowToFullScreenIfNecessary,在init初期就是纠正道正确尺寸,所以window的大小永远是正确的屏幕尺寸大小。这里和AppDelegate很像。

当你的window 设置了rootController,并且调用了makeKeyAndVisible时,rootController 会调用自己的view方法,然后开始回事loadview 从xib或者SB中加载view了,这是你的xib 或者SB 决定着 你的Controller执行到viewdidload 方法时的self.view 的大小。xib或者SB你选择的屏幕的大小,就是到viewdidload 时view的大小,所以显然你不能在不同手机尺寸,来根据你的self.view的frame 来布局你的subViews是错误的,所以现在所有使用frame的人都会使用UIscreen的bounds来获取当前屏幕尺寸。
此时只要删除xib或者SB就可以了。
其实self.view纠正貌似来自viewcontorller 的'-[UIViewController _window]的大小纠正,底层来自CALayer::这个C++类的纠正

一切viewcontroller.view 的subviews 开始布局在viewcontroller调完viewWillLayoutSubviews这个方法之后。但是有人就想问的更深一些,经过研究发现,是在view.layer 的代理方法开始布局的,layoutSublayersOfLayer:,这个代理方法默认指向view自己的.

/* Called by the default -layoutSublayers implementation before the layout
 * manager is checked. Note that if the delegate method is invoked, the
 * layout manager will be ignored. */

- (void)layoutSublayersOfLayer:(CALayer *)layer;

另一处是:

/* Called when the layer requires layout. The default implementation
 * calls the layout manager if one exists and it implements the
 * -layoutSublayersOfLayer: method. Subclasses can override this to
 * provide their own layout algorithm, which should set the frame of
 * each sublayer. */

- (void)layoutSublayers;

由此可见只要你默认不实现这个代理方法他会用他自己的layout algorithm(layout 算法),只要你自己实现了,你要写一套布局算法,或者手动设置frame布局也可。
这个算法经过调试就是View自己的私有方法的算法-[view _layoutEngine],这是个私有类->NSISEngine.
我获取了NSISEngine所有的属性和方法

in NSISEngine:
    Class Methods:
        + (BOOL) _dbg_anyEngineContainsVariable:(id)arg1; (0x7fff59a25c40)
        + (void) setEnableEngineTrace:(BOOL)arg1; (0x7fff59a285ee)
        + (BOOL) enableEngineTrace; (0x7fff59a285fa)
        + (id) traceFileSuffix; (0x7fff59a28604)
        + (void) setTraceFileSuffix:(id)arg1; (0x7fff59a2860c)
        + (void) setLogOnInvalidUseFromBGThread:(BOOL)arg1; (0x7fff59a2861a)
    Properties:
        @property (retain) NSMutableArray* variablesWithValueRestrictionViolations;  (@synthesize variablesWithValueRestrictionViolations = _variablesWithValueRestrictionViolations;)
        @property (retain) NSISVariable* artificialRowHead;  (@synthesize artificialRowHead = _artificialRowHead;)
        @property (retain) NSISVariable* artificialObjectiveRowHead;  (@synthesize artificialObjectiveRowHead = _artificialObjectiveRowHead;)
        @property (retain) NSISObjectiveLinearExpression* artificialObjectiveRowBody;  (@synthesize artificialObjectiveRowBody = _artificialObjectiveRowBody;)
        @property <NSISEngineDelegate>* delegate;  (@synthesize delegate = _delegate;)
        @property BOOL shouldIntegralize;
        @property BOOL revertsAfterUnsatisfiabilityHandler;  (@synthesize revertsAfterUnsatisfiabilityHandler = _revertsAfterUnsatisfiabilityHandler;)
        @property (readonly) unsigned long variableChangeCount;
        @property (readonly, getter=isOptimizationInProgress) BOOL optimizationInProgress;
        @property (nonatomic) struct CGSize engineScalingCoefficients;  (@synthesize engineScalingCoefficients = _engineScalingCoefficients;)
        @property (readonly) unsigned long hash;
        @property (readonly) Class superclass;
        @property (readonly, copy) NSString* description;
        @property (readonly, copy) NSString* debugDescription;
    Instance Methods:
        - (id) debugQuickLookObject; (0x7fff24ae85b2)
        - (void) _UIKitPerformPendingChangeNotifications; (0x7fff24af0442)
        - (BOOL) _UIKitEngineTrackingOn; (0x7fff24af042a)
        - (void) _setUIKitEngineTrackingOn:(BOOL)arg1; (0x7fff24af03dc)
        - (unsigned long) _UIKitRowCount; (0x7fff24af0497)
        - (void) dealloc; (0x7fff59a23bc5)
        - (id) description; (0x7fff59a288c6)
        - (id) init; (0x7fff59a238ff)
        - (id) delegate; (0x7fff59a2bc5a)
        - (void) setDelegate:(id)arg1; (0x7fff59a2bc64)
        - (unsigned long) rowCount; (0x7fff59a28801)
        - (id) constraints; (0x7fff59a2877e)
        - (void) setShouldIntegralize:(BOOL)arg1; (0x7fff59a1f2a8)
        - (void) setEngineScalingCoefficients:(struct CGSize)arg1; (0x7fff59a2bc98)
        - (void) withAutomaticOptimizationDisabled:(^block)arg1; (0x7fff59a2511d)
        - (struct ?*) traceState; (0x7fff59a28612)
        - (struct CGSize) engineScalingCoefficients; (0x7fff59a2bc88)
        - (double) valueForVariable:(id)arg1; (0x7fff59a2516b)
        - (BOOL) hasValue:(double*)arg1 forVariable:(id)arg2; (0x7fff59a25282)
        - (BOOL) isObservingChangesForVariable:(id)arg1; (0x7fff59a285ce)
        - (void) performPendingChangeNotifications; (0x7fff59a1f872)
        - (id) candidateRedundantConstraints; (0x7fff59a2ab6d)
        - (id) constraintsAffectingValueOfVariable:(id)arg1; (0x7fff59a2a9bf)
        - (BOOL) exerciseAmbiguityInVariable:(id)arg1; (0x7fff59a2ba71)
        - (void) stopObservingChangesForVariable:(id)arg1; (0x7fff59a28536)
        - (void) removeObservableForVariable:(id)arg1; (0x7fff59a28413)
        - (void) nsis_valueOfVariable:(id)arg1 didChangeInEngine:(id)arg2; (0x7fff59a1f1fc)
        - (id) nsis_descriptionOfVariable:(id)arg1; (0x7fff59a1f20a)
        - (int) nsis_orientationHintForVariable:(id)arg1; (0x7fff59a1f28f)
        - (BOOL) nsis_valueOfVariableIsUserObservable:(id)arg1; (0x7fff59a1f202)
        - (BOOL) valueOfVariableIsAmbiguous:(id)arg1; (0x7fff59a2b998)
        - (unsigned long) variableChangeCount; (0x7fff59a288b0)
        - (void) startObservingChangesForVariable:(id)arg1; (0x7fff59a2847b)
        - (id) observableForVariable:(id)arg1; (0x7fff59a28376)
        - (unsigned long) optimize; (0x7fff59a243fd)
        - (void) beginRecording; (0x7fff59a241f6)
        - (unsigned long) colCount; (0x7fff59a28855)
        - (void) endBookkeepingForVariableIfUnused:(id)arg1; (0x7fff59a25b6e)
        - (id) variableChangeTransactionSignal; (0x7fff59a285a5)
        - (double) valueForExpression:(id)arg1; (0x7fff59a25607)
        - (id) variableForEngineVarIndex:(struct ?)arg1; (0x7fff59a241a3)
        - (int) valueRestrictionForEngineVarIndex:(struct ?)arg1; (0x7fff59a241cc)
        - (void) verifyInternalIntegrity; (0x7fff59a29076)
        - (id) _brokenConstraintPositiveErrorsIfAvailable; (0x7fff59a1eaae)
        - (id) _brokenConstraintNegativeErrorsIfAvailable; (0x7fff59a1edf1)
        - (void) enumerateRows:(^block)arg1; (0x7fff59a2592e)
        - (void) removeConstraintWithMarker:(id)arg1; (0x7fff59a27734)
        - (void) setVariablesWithValueRestrictionViolations:(id)arg1; (0x7fff59a2bc4b)
        - (void) withoutOptimizingAtEndRunBlockWithAutomaticOptimizationDisabled:(^block)arg1; (0x7fff59a25137)
        - (unsigned long) _optimizeWithoutRebuilding; (0x7fff59a248f0)
        - (void) withBehaviors:(unsigned long)arg1 performModifications:(^block)arg2; (0x7fff59a24efc)
        - (BOOL) tryToAddConstraintWithMarker:(id)arg1 expression:(id)arg2 mutuallyExclusiveConstraints:(id*)arg3; (0x7fff59a25c86)
        - (BOOL) containsVariable:(id)arg1; (0x7fff59a25876)
        - (void) constraintDidChangeSuchThatMarker:(id)arg1 shouldBeReplacedByMarkerPlusDelta:(double)arg2; (0x7fff59a28094)
        - (double) integralizationAdjustmentForMarker:(id)arg1; (0x7fff59a1f297)
        - (BOOL) shouldIntegralize; (0x7fff59a1f2a0)
        - (BOOL) isTrackingVariableChanges; (0x7fff59a1f868)
        - (void) performPendingChangeNotificationsForItem:(id)arg1; (0x7fff59a1fcd7)
        - (void) performModifications:(^block)arg1 withUnsatisfiableConstraintsHandler:(^block)arg2; (0x7fff59a21bbb)
        - (struct ?) engineVarIndexForVariable:(id)arg1; (0x7fff59a24192)
        - (id) recordedCommandsData; (0x7fff59a2421d)
        - (unsigned long) replayCommandsData:(id)arg1 verifyingIntegrity:(BOOL)arg2; (0x7fff59a2424e)
        - (void) withDelegateCallsDisabled:(^block)arg1; (0x7fff59a25151)
        - (BOOL) hasValueForPossiblyDeallocatedVariable:(id)arg1; (0x7fff59a25473)
        - (BOOL) hasValue:(double*)arg1 forExpression:(id)arg2; (0x7fff59a25726)
        - (void) beginBookkeepingForVariableIfNeeded:(id)arg1; (0x7fff59a25b61)
        - (BOOL) tryToAddConstraintWithMarker:(id)arg1 expression:(id)arg2 integralizationAdjustment:(double)arg3 mutuallyExclusiveConstraints:(id*)arg4; (0x7fff59a25c74)
        - (void) addVariableToBeOptimized:(id)arg1 priority:(double)arg2; (0x7fff59a265ba)
        - (void) removeVariableToBeOptimized:(id)arg1 priority:(double)arg2; (0x7fff59a2678d)
        - (void) changeVariableToBeOptimized:(id)arg1 fromPriority:(double)arg2 toPriority:(double)arg3; (0x7fff59a26ab3)
        - (BOOL) containsConstraintWithMarker:(id)arg1; (0x7fff59a27722)
        - (BOOL) tryToChangeConstraintSuchThatMarker:(id)arg1 isReplacedByMarkerPlusDelta:(double)arg2 undoHandler:(^block)arg3; (0x7fff59a281ca)
        - (BOOL) hasObservableForVariable:(id)arg1; (0x7fff59a2845e)
        - (unsigned long) pivotCount; (0x7fff59a288a6)
        - (BOOL) isOptimizationInProgress; (0x7fff59a288ba)
        - (id) allVariableValues; (0x7fff59a2bb65)
        - (id) variablesWithValueRestrictionViolations; (0x7fff59a2bc37)
        - (BOOL) revertsAfterUnsatisfiabilityHandler; (0x7fff59a2bc6e)
        - (void) setRevertsAfterUnsatisfiabilityHandler:(BOOL)arg1; (0x7fff59a2bc7c)
        - (id) artificialRowHead; (0x7fff59a2bca8)
        - (void) setArtificialRowHead:(id)arg1; (0x7fff59a2bcbc)
        - (id) artificialObjectiveRowHead; (0x7fff59a2bccb)
        - (void) setArtificialObjectiveRowHead:(id)arg1; (0x7fff59a2bcdf)
        - (id) artificialObjectiveRowBody; (0x7fff59a2bcee)
        - (void) setArtificialObjectiveRowBody:(id)arg1; (0x7fff59a2bd02)

NSISEngine 的@property <NSISEngineDelegate>* delegate;是指向view自己的。
听说这个算法是个先行方程,这里不做研究了。少研究算法,保护好自己的头发。不感兴趣,作为无谓的自我伤害不值得。

-[CALayer layoutSublayers]: 
↓
-[UIView(CALayerDelegate) layoutSublayersOfLayer:] 
↓
-[UIView _updateConstraintsAsNecessaryAndApplyLayoutFromEngine]
↓
-[UIView(AdditionalLayoutSupport) _is_layout]
↓
-[UIView resizeSubviewsWithOldSize:]

其中上图第二步至关重要,他来自UIKitCore(UIKitCore``-[UIView(CALayerDelegate) layoutSublayersOfLayer:]),如果你不实现layoutSublayersOfLayer:代理方法,他就选择走UIView的CALayerDelegate分类。然后用_layoutEngine去布局。

下面我们既使用系统的布局引擎,同时又可拦截布局的方法:
ex:

-(void)layoutSublayersOfLayer:(CALayer *)layer {

    [super layoutSublayersOfLayer:layer];
    // 可以布局一些未布局的view 或者CALayer
}

自己只会布局subview 布局。自己的布局要看自己所添加的上层view 对自己的布局.自己没有对上层view添加自己的布局约束,就会走frame。不会影响subview 的布局。frame和autolayout 可以共存。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容