美文网首页
自动布局-SDAutoLayout

自动布局-SDAutoLayout

作者: RichieQ | 来源:发表于2018-02-28 14:06 被阅读0次

    一、简介

    SDAutoLayout是基于对frame进行设置的一直布局,被依赖的view布局要写在前面,不然有可能造成界面异常(或者布局后面添加[被依赖的view updateLayout],手动进行刷新)

    二、原理

    view是没有sd_layout属性的,作者使用动态关联,扩展UIView, 调用getter方法时sd_layout对象生成,此对象作为view对象的布局控制模块, 每次生成一个sd_layout对象,都把它加为super viewautolayoutModelsArray中,sd_layout对象即SDAutoLyaout的实例,SDAutoLayout下设left, top, bottom, right等对象负责具体的布局... 用文字解释不了,看个图:

    可见作者的面向对象思想是相当牛B的。

    当我们调用 view.sd_layout.leftSpaceToView(self.view, 20) 时,sd_layout 对象的leftSpaceToView 是个懒加载的block, 我们这样是调用这个block, 这样在内部SDAutoLayout对frame进行赋值,所以,SDAutoLayout并不像其名字AutoLayout所示通过NSLayoutConstraint来对view进行布局的,它是本质上通过修改视图的frame来处理的。

    继续:当调用[someView updateLayout]的时候,我们顺着API找下去:

    // UIView的Category中:
    - (void)updateLayout
    {
        [self.superview layoutSubviews];
    }
    
    

    也就是说,当对一个view updateLayout的时候,它会调其父视图的layoutSubviews, 而当调用layoutSubviews时,SDAutoLayout使用方法交换,调用sd_layoutSubviews,我们可以看到交换方法的源代码:

    + (void)load
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
    
            NSArray *selStringsArray = @[@"setText:"];
    
            [selStringsArray enumerateObjectsUsingBlock:^(NSString *selString, NSUInteger idx, BOOL *stop) {
                NSString *mySelString = [@"sd_" stringByAppendingString:selString];
    
                Method originalMethod = class_getInstanceMethod(self, NSSelectorFromString(selString));
                Method myMethod = class_getInstanceMethod(self, NSSelectorFromString(mySelString));
                method_exchangeImplementations(originalMethod, myMethod);
            }];
        });
    }
    
    

    调用sd_layoutSubviews

    // UIView的Category中:
    - (void)sd_layoutSubviews
    {
        [self sd_layoutSubviews]; // 此处由于方法交换,调用[self layoutSubviews]   
        [self sd_layoutSubviewsHandle];
    }
    
    

    sd_layoutSubviewsHandle中,我们知道,看上面图中视图有一个autolayoutModelsArray,它记录着其所有子视图用SDAutoLayout布局的对象,并可以找到每一个子视图所关联着的SDAutoLayout对象,所它来布局。上面谈到,在SDAutoLayout中有left, top, bottom, right等具体的对象,在这些对象中都有一个refView代表其所参照的视图,我们可以把它想像成链表,链表的上一个节点动了,其被参照的视图根据refView找到前一个节点,从而作刷新。

    三、实现

    参考github上的Demo

    借鉴愤怒的振振的文章https://www.jianshu.com/p/2ddf29e029fe

    相关文章

      网友评论

          本文标题:自动布局-SDAutoLayout

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