当使用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它的约束已经设置。你可以尝试很多不同的东西,
实现UIView
的layoutSubviews
函数,当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的框架。好运!