UIViewController viewDidLoad不正确的宽度/高度

ksn*_*ksn 10 objective-c uiview ios

大家都知道你不能相信UIViewController init/viewDidLoad方法的帧大小; 这个:

- (void)viewDidLoad: {
     NSLog(@"%d", self.view.frame.size.width);
}
Run Code Online (Sandbox Code Playgroud)

将在许多场合打印错误的尺寸(特别是它在横向模式下几乎被打破)

这实际上将返回始终更正的结果,因此布局子视图是好的:

- (void)viewWillAppear: {
     NSLog(@"%d", self.view.frame.size.width);
}
Run Code Online (Sandbox Code Playgroud)

问题是每次出现视图时都会调用viewWillAppears,因此不适合分配或添加子视图.因此,您最终会 在界面中声明每个单独的视图,并最终得到我根本不喜欢的大量头文件,因为大多数项目在初始设置后不需要再进行任何操作.

所以问题是:有没有更好的方法来处理子视图定位?

问题二是非常相关的,假设我有一个UIView的子类,包括其他各种子视图.我在我的界面中声明它,并在我的init/viewDidLoad方法中分配/初始化它.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    ...
    menu = [[SNKSlidingMenu alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    ...
}
Run Code Online (Sandbox Code Playgroud)

正如我们已经知道的那样,我们现在需要在viewWillAppear中重新定位它以获得更准确的读数

- (void)viewWillAppear:(BOOL)animated{
    ....
    menu.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    ....
 }
Run Code Online (Sandbox Code Playgroud)

问题是当然所有子视图也需要重新定位.这是由自动调用的layoutSubviews函数完成的,但是我们遇到了同样的问题:所有子视图都需要在SNKSlidingMenu类的接口内声明.有没有办法解决这个问题?

谢谢.

pgb*_*pgb 10

如果您的目标是iOS 5.0或更高版本,则可以使用viewWillLayoutSubviewsviewDidLayoutSubviews进行更改.

至于你的第二个问题,如果你需要以其他方法访问实例变量init,你需要保留它,我没有看到它的问题.

但是,您可以尝试使用自动布局并在子视图之间设置规则,以便自动为您布局,而无需保留参考.


Aar*_*ger 6

viewDidLoad只有在创建视图时才会调用,但很多事情都会影响其frame大小,并且在frame更改时不会再次调用它.

代替:

  • 在中创建子视图 viewDidLoad
  • 设定他们的尺寸 viewWillLayoutSubviews.

请参阅此处有关处理轮换的其他讨论:https://stackoverflow.com/a/16421170/1445366


小智 5

viewWillLayoutSubviews并且viewDidLayoutSubviews可以解决这个问题。
但是这两种方法会被执行更多次。这是我的正确代码self.view.frame

- (void)viewDidLoad {
  [super viewDidLoad];  
  ...  
  dispatch_async(dispatch_get_main_queue(), ^{  
   // init you view and set it`s frame. this can get correct frame.   
   ...  
  }  
  ...  
}
Run Code Online (Sandbox Code Playgroud)