我们只能在viewDidAppear中正确配置UI吗?而不是在viewWillAppear / viewDidLoad?

时间:2017-12-13 10:50:06

标签: objective-c viewdidload viewwillappear viewdidappear

我有一个静态表视图,其中的单元格具有圆角边框。我注意到在不同的模拟器上测试时,虽然我的自动布局约束工作,但边框并不总是正确的宽度。此特定屏幕包含一个视图控制器,其中UIView包含嵌入的tableViewController

我做了一些调查,发现边框的宽度实际上取决于故事板手机的宽度。这意味着如果我有一个iPhone 8的故事板,8 +将有太短的细胞,反之亦然,8 +故事板导致细胞太长(并延伸到屏幕外)为8。

目前我在viewDidLoad中设置单元格边框,这是我用来配置单元格边框的代码:

- (void)configureCellThree {
    //Add Border
    CALayer *borderLayer = [CALayer layer];
    CGRect borderFrame = CGRectMake(0, 0, (_contentCellThree.frame.size.width), (_contentCellThree.frame.size.height));
    [borderLayer setBackgroundColor:[[UIColor clearColor] CGColor]];
    [borderLayer setFrame:borderFrame];
    [borderLayer setCornerRadius:_contentCellThree.frame.size.height / 2];
    [borderLayer setBorderWidth:1.0];
    [borderLayer setBorderColor:[kTextColor2 CGColor]];
    // [borderLayer setOpacity:0.5];
    [_contentCellThree.layer addSublayer:borderLayer];
}

现在如果我在viewDidAppear中运行此代码,一切都可以在两个设备上运行。我在主视图控制器中添加了一些日志,以了解事情的设置方式。

- (void)viewDidLoad {

    [super viewDidLoad];

    NSLog(@"VDL - SELF.VIEW = %@", self.view);
    NSLog(@"VDL - CONTAINER VIEW = %@", self.profileScrollingContainerView);
}

- (void)viewDidAppear:(BOOL)animated {

    [super viewDidAppear:animated];

    NSLog(@"VDA- SELF.VIEW = %@", self.view);
    NSLog(@"VDA - CONTAINER VIEW = %@", self.profileScrollingContainerView);
}

我怀疑viewDidLoad正在使用故事板中的大小调整信息而不是视图本身(这似乎不正确)。此日志记录确认了这一点。如果我查看负责显示我的tableview的UIView,当故事板设置为8+时,它具有以下框架属性:X = 0, Y = 349, W = 414, H = 338。现在让我们看一下日志记录的结​​果:

VDL - SELF.VIEW = <UIView: 0x7fa545401f10; frame = (0 0; 375 667); 
VDL - CONTAINER VIEW = <UIView: 0x7fa545401b50; frame = (0 349; 414 338); 


VDA- SELF.VIEW = <UIView: 0x7fa545401f10; frame = (0 64; 375 603); 
VDA - CONTAINER VIEW = <UIView: 0x7fa545401b50; frame = (0 285; 375 269);

因此,当视图加载时,tableview会获取有关视图大小的错误信息。当viewDidAppear被调用时,它具有正确的视图大小并且将正常工作。我的问题是我不想在viewDidAppear中调用初始化代码。

I read here that I should be putting my UI Geometry code into the viewWillAppear但是我已经尝试了这个并且我遇到了同样的问题。

VWA - CONTAINER VIEW = <UIView: 0x7fec04d97700; frame = (0 349; 414 338);

所以为了巩固我的问题,如何在视图加载/出现之前获取视图的属性,以便我可以正确设置我的UI?

我已经读过我需要继承UIView并可能使用setFrame但是我真的不知道我实际上是怎么做的。

2 个答案:

答案 0 :(得分:0)

事实证明我使用了错误的方法来做到这一点。 I found this question which solved my whole issue.基本上,如果您需要执行UI计算(例如添加自定义视图),您应该在-(void)viewDidLayoutSubviews中执行它们。在视图计算出所有大小和约束之后调用此方法,因此您在此处执行的任何操作都将使用视图的正确属性执行!

答案 1 :(得分:0)

子类UITableViewCell并实现layoutSubviews,即参见docs

“子类可以根据需要重写此方法,以对其子视图执行更精确的布局。仅当子视图的自动调整大小和基于约束的行为未提供所需的行为时,才应覆盖此方法。可以使用您的实现直接设置子视图的框架矩形。”