美文网首页
从加载Controller到View显示,autoLayout是

从加载Controller到View显示,autoLayout是

作者: xiaoliang1 | 来源:发表于2021-04-29 14:31 被阅读0次

    首先,当你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 可以共存。

    相关文章

      网友评论

          本文标题:从加载Controller到View显示,autoLayout是

          本文链接:https://www.haomeiwen.com/subject/jlvirltx.html