UIView能知道它的布局过程已经完成吗?

  • 本文关键字:过程 布局 UIView ios
  • 更新时间 :
  • 英文 :


当使用auto layout时,视图的大小在初始化时是未知的,这给我带来了一个问题。

当使用UIImageView时,我写了一个类别,可以通过将图像URL设置为UIImageView从我自己的CDN加载图像,我的CDN存储一个不同大小的图像,以便不同的设备可以加载它真正需要的大小。

我想让我的UIImageView能够加载URL的分辨率需要,但当我的UIImageView得到URL,它的大小还没有由auto layout确定。

是否有一种方法让UIView知道它的布局过程第一次完成了?

有一个UIView的方法。你可以重写它

-(void)layoutSubviews {
    CGRect bounds =self.bounds;
    //build your imageView's frame here
    self.imageView=imageViewFrame.
}

在Swift 5。X

override func layoutSubviews() {
    super.layoutSubviews()
    let myFrame = = self.bounds
}

如果您在自定义视图中有其他复杂的项,不要忘记在覆盖layoutSubviews()时调用super…

遗憾的是,没有直接的方法可以通知UIView它的约束已经设置。你可以尝试很多不同的东西,

实现UIViewlayoutSubviews函数,当UIView的布局改变时调用。

UIViewController中实现viewDidLayoutSubviews。当所有的布局都设置好后,这个函数被调用。此时,您可以创建类别函数。

这是一个测试,我只使用自动布局,我只使用自定义子类的子视图。我在子类的初始化器中做了所有的自动布局:

这是一个"登录"按钮。它没有框架,但是用autolayout:

设置
-(void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    if (self.contentView.loginButton.frame.size.height) {
        NSLog(@"viewDidLayoutSubviews");
    }
}
-(void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    if (self.contentView.loginButton.frame.size.height) {
        NSLog(@"viewWillLayoutSubviews");
    }
}
-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}
-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (self.contentView.loginButton.frame.size.height) {
        NSLog(@"didAppear");
    }
}
-(void)viewWillAppear:(BOOL)animated {
    if (self.contentView.loginButton.frame.size.height) {
        NSLog(@"viewWillAppear");
    }
}
-(void)viewDidLoad {
    [super viewDidLoad];
    if (self.contentView.loginButton.frame.size.height) {
        NSLog(@"viewDidLoad");
    }
}

输出如下。这意味着我的视图终于有了一个框架当

2015-08-25 01:28:27.789 [67502:11 183631] viewDidLayoutSubviews

2015-08-25 01:28:27.790 [67502:11 183631] viewWillLayoutSubviews

2015-08-25 01:28:27.790 [67502:11 183631] viewDidLayoutSubviews

2015-08-25 01:28:28.007 [67502:11 183631] didAppear

这意味着第一次登录按钮有一个框架是在viewDidLayoutSubviews,这将看起来很奇怪,因为这是主视图的子视图的第一次传递。ViewWillAppear中没有框架,尽管视图控制器本身的视图在login按钮之前已经设置好了。当视图控制器的视图被设置时,整个UIView子类的主视图也被设置,这也发生在login按钮之前。因此,视图的子视图是在父视图设置之后设置的。

关键是:如果你把imageview信息拉进viewDidLayoutSubviews,那么你就有了一个框架来工作,除非你通过类型投射将这个UIImageView框架设置为ViewController的视图,那么你将在viewDidLoad中设置UIImageView的框架。好运!

最新更新