I am trying to add a UITableView
object that covers up the whole screen, by
UITableView *tabelView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:tabelView];
but I realized that even if a physical iPad 2 is rotated to Landscape mode, self.view.bounds
is {{0, 0}, {768, 1004}}
in viewDidLoad
and viewWillAppear
. Only in viewDidAppear
is it finally {{0, 0}, {1024, 748}}
What is the earliest time that self.view.bounds
is set correctly to {{0, 0}, {1024, 748}}
? If viewDidAppear
is the one, then I have to create the UITableView
there, and if the "Launch image" is a static Landscape blank table, then the screen will flash a white screen when viewDidAppear
is called, and then the table is added and seen, so a flash of white screen is seen.
So when is the earliest time that self.view.bounds
is set correctly to {{0, 0}, {1024, 748}}
? It seems like it needs to be slightly before viewDidAppear
, so that the blank table is drawn (with the grey lines), and show it and seamlessly get displayed to cover up the Launch image. If the table is created in viewDidLoad
or viewWillAppear
using self.view.bounds
, then the table ends up being 768 points wide and is meant for the Portrait mode.
Update: I just tried to add the Launch image and for some reason, even if the UITableView
is added in viewDidAppear
, the "flash of white screen" didn't happen... I don't know why, but previously if I use CALayer
and bitmap to show content, and didn't use any view or drawRect
, then the flash occurred... by the way, the earliest one I found was viewWillLayoutSubviews
, and then later in viewDidLayoutSubviews
, both of which happened before viewDidAppear
, and both showed self.view.bounds
as {{0, 0}, {1024, 748}}
Update 2: What if the view is complicated and time consuming to make? To test, I added a usleep(100000);
in the tableView:cellForRowAtIndexPath
to sleep 0.1 second for each cell, and the "flash" did occur... but cell and table supposedly should be light weight and fast to make, but what if there are other type of views that are more time consuming to make? If I move UITableView
creation to viewWillLayoutSubviews
, then it is still slow to show something, but at least there is no "flash". However, later on when I rotate the device, it actually call viewWillLayoutSubviews
again and add another table to the main view (with correct screen size), so viewWillLayoutSubviews
will need to remove any old table view first, if any, or just resize the old one and not add a new one.
Frame refers to the coordinate system of the view's container (parent view). Bounds refer to the own coordinate system of the view.
frame = a view's location and size using the parent view's coordinate system (important for placing the view in the parent) bounds = a view's location and size using its own coordinate system (important for placing the view's content or subviews within itself)
If you need to be told when a particular subview changes size, and know its exact final size, you should generally override the layoutSubviews method of that particular UIView subclass.
The simplest way to avoid the flash is to create the table view in viewDidLoad
and set the table view's autoresizing mask properly, so that the system automatically makes the table view fill its superview:
- (void)viewDidLoad {
[super viewDidLoad];
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:tableView];
}
Otherwise, the earliest time that you can see the final view bounds are in the view controller's viewWillLayoutSubviews
method. You would add your table view once in viewDidLoad
, and then adjust its frame in viewWillLayoutSubviews
or a method called after that. See my answer to UIViewController returns invalid frame? for more details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With