我应该把 AutoLayout 代码放在哪里?

Posted

技术标签:

【中文标题】我应该把 AutoLayout 代码放在哪里?【英文标题】:Where should I put AutoLayout code? 【发布时间】:2015-07-13 06:38:51 【问题描述】:

我正在使用PureLayout 在 UIView 中实现子视图的自动布局。但我不知道组织代码的最佳实践。

应该把AutoLayout相关的代码放在UIView的init中,还是updateConstraintslayoutSubviews等被覆盖的方法里?

【问题讨论】:

设置在init就可以了 【参考方案1】:

比如我想创建一个UIView的子类叫PHView,对于任何一个phview,都有一个叫centerView的子视图,它总是在phview的中心,width/height是0.3*phview的width/height。 https://www.dropbox.com/s/jaljggnymxliu1e/IMG_3178.jpg

 #import "PHView.h"
 #import "Masonry.h"
@interface PHView()
@property (nonatomic, assign) BOOL didUpdateConstraints;
@property (nonatomic, strong) UIView *centerView;
@end
@implementation PHView
- (instancetype)init 
    self = [super init];
    if (self) 
        self.backgroundColor = [UIColor redColor];
        self.translatesAutoresizingMaskIntoConstraints = NO;
    
    return self;

 - (UIView *)centerView 
    if (!_centerView) 
        _centerView = [UIView new];
        _centerView.backgroundColor = [UIColor yellowColor];
        [self addSubview:_centerView];
    
    return _centerView;


 -(void)updateConstraints 
    if (!_didUpdateConstraints) 
        _didUpdateConstraints = YES;
        [self.centerView mas_makeConstraints:^(MASConstraintMaker *make) 
            make.centerX.equalTo(self.mas_centerX);
            make.centerY.equalTo(self.mas_centerY);
            make.width.equalTo(self.mas_width).multipliedBy(0.3);
            make.height.equalTo(self.mas_height).multipliedBy(0.3);
        ];
    
    [super updateConstraints];

@end

'didUpdateConstraints' 旨在表明您已添加约束,因此您只会添加一次约束。

在 UIViewController:make phview top left bottom right 20 to margin.

- (void)viewDidLoad 
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor greenColor];
    PHView *myView = [PHView new];
    [self.view addSubview:myView];
    [myView mas_makeConstraints:^(MASConstraintMaker *make) 
        make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(20, 20, 20, 20));
    ];


【讨论】:

【参考方案2】:

当您确定view 已添加到其superview 时,您应该添加constraints。基本上,您应该在调用addSubview: 之后的任何时间点在superview 的课程中​​执行此操作。

回答您的问题:

1-init 方法中,您能确定view 已作为subview 添加到superview 中吗?假设这一点是不安全的。也许你可以在superviewinit方法中添加constraints

2- layoutSubviewsautolayout 代码实际工作的地方。你不能在layoutSubviews 中添加constraints。已经在玩autolayout constraints 并不便宜,因此您应该尽可能少地添加/删除它们,以多次调用的方法(即layoutSubviews)这样做不是最佳做法。

autolayout 的机制是从外部view 进入内部view,所以subviews 实际上并不关心constraints。这是superview的责任

【讨论】:

但我通常会在自定义单元格中的 `layoutSubviews' 中进行约束,它可以工作。 这可能会导致多一次布局传递,这不是最佳做法。如果您关心的是表格视图单元格,您可以考虑在 awakeFromNib 中添加约束。因为在这种情况下,您的超级视图是单元格并且在 awakeFromNib【参考方案3】:

希望这可以帮助您了解控制器的视图层次结构 视图控制器如何参与视图布局过程

    视图控制器的视图调整为新大小。 如果未使用自动布局,则视图会根据其自动调整大小的掩码调整大小。 视图控制器的 viewWillLayoutSubviews 方法被调用。

    视图的 layoutSubviews 方法被调用。如果使用自动布局来配置视图层次结构,它会通过执行以下步骤来更新布局约束:

    a.调用视图控制器的 updateViewConstraints 方法。

    b.UIViewController 类的 updateViewConstraints 方法实现调用视图的 updateConstraints 方法。

    c。布局约束更新后,计算新布局并重新定位视图。

    视图控制器的 viewDidLayoutSubviews 方法被调用。

请refer this了解更多详情

【讨论】:

以上是关于我应该把 AutoLayout 代码放在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

如果“实用程序”类是邪恶的,我应该把我的通用代码放在哪里? [关闭]

我应该把函数放在哪里?

我在哪里把自定义代码放在 Laravel

我应该把我的 DTO 放在哪里?

我应该如何构建一个 Java 应用程序,我应该把我的类放在哪里?

我应该把dll文件放在哪里(我在我的项目中使用)