本文介绍了无法在 viewDidAppear 之前正确设置框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有人知道为什么当您在 viewDidLoadviewWillAppear 中设置子视图的框架时,更改不会在屏幕上生效,但是如果您设置在 viewDidAppear 中他们做了什么?

I was wondering if anyone knows why when you set the frame of a subview in viewDidLoad and viewWillAppear the changes do not take affect on the screen, but if you set it in viewDidAppear they do?

在我的情况下,我正在加载一个带有两个 tableview 的自定义 xib,然后尝试在 viewDidLoad 中将它们向下移动,以便为在 viewDidLoad 中添加的另一个视图留出空间并不总是需要显示它.

In my case I am loading a custom xib with two tableviews then attempting to shift them down in viewDidLoad to allow space for another view which is added in viewDidLoad as it is not always necessary to display it.

问题是当我在 viewDidLoadviewWillAppear 中设置框架时,它被设置在对象上,我可以通过打印出来看到它,但它没有反映在屏幕上.将我的设置框架调用移动到 viewDidAppear 将使一切按预期工作.

The problem is when i set frame in viewDidLoad or viewWillAppear it is set on the object, i can see by printing it out, but it is not reflected on screen. Moving my set frame calls to viewDidAppear will cause everything to work as expected.

认为我应该能够在 viewDidLoad 中设置框架是错误的吗?

Is it wrong to think I should be able to set the frame in viewDidLoad?

- (id)init {
    if ( self = [super initWithNibName:@"MyView" bundle:nil] ) {}

    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.descriptionWebView = [[[UIWebView alloc] initWithFrame:CGRectMake( 0, 0, self.view.frame.size.width, 200 )] autorelease];

    [self.view addSubview:self.descriptionWebView];

    self.tableView1.autoresizingMask = UIViewAutoresizingNone;
    self.tableView2.autoresizingMask = UIViewAutoresizingNone;

    [self.descriptionWebView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"...." withExtension:@"html"]]];

    table1LocationWithHeader = CGRectMake( self.tableView1.frame.origin.x, 200, self.tableView1.frame.size.width, self.tableView1.frame.size.height - 200 );
    table2LocationWithHeader = CGRectMake( self.tableView2.frame.origin.x, 200, self.tableView2.frame.size.width, self.tableView2.frame.size.height - 200 );

    //this will NOT work
    self.tableView1.frame = table1LocationWithHeader;
    self.tableView2.frame = table2LocationWithHeader;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    //this will NOT work
    self.tableView1.frame = table1LocationWithHeader;
    self.tableView2.frame = table2LocationWithHeader;
}


- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    //this WILL work
    self.tableView1.frame = table1LocationWithHeader;
    self.tableView2.frame = table2LocationWithHeader;
}


//I added these after comments for stack overflow users, it seems like viewDidLayoutSubviews is the best place to set the frame

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    //this will NOT work
    self.tableView1.frame = table1LocationWithHeader;
    self.tableView2.frame = table2LocationWithHeader;
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    //this WILL work
    self.tableView1.frame = table1LocationWithHeader;
    self.tableView2.frame = table2LocationWithHeader;
}

推荐答案

viewDidLoad 在类加载时被调用,但是没有 ui 元素被初始化,因此在初始化过程中任何试图引用它们的尝试都将被覆盖或不可用在 viewDidLoad 和 viewDidAppear 调用之间.一旦所有 ui 元素都已初始化并绘制,viewDidAppear 将被调用.

viewDidLoad is called when the class is loaded however no ui elements have been initialised and therefore any attempt to reference them will be overwritten or unavaliable during the initialisation process which happens between the viewDidLoad and viewDidAppear calls. Once all ui element have been initalised and drawn viewDidAppear is called.

viewDidLoad -在控制器的视图加载到内存后调用

此时视图不在视图层次结构中.

At this point the view isn't within the view hierarchy.

viewWillAppear - 通知视图控制器其视图即将添加到视图层次结构中.

同样,视图尚未添加到视图层次结构中.

Again, the view is yet to be added to the view hierarchy.

viewDidAppear - 通知视图控制器其视图已添加到视图层次结构中.

只有这样,视图才会添加到视图层次结构中.

Only then is the view added to the view hierarchy.

更新

viewDidLayoutSubviews 是在 UI 实际出现在屏幕上之前对其进行修改的最合适的位置.

The viewDidLayoutSubviews is the most appropriate place to modify the UI before it actually appears on the screen.

viewDidLayoutSubviews - 通知视图控制器它的视图刚刚布局了它的子视图.

这篇关于无法在 viewDidAppear 之前正确设置框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 09:15