I've got a really strange bug in my project. I've got a UIScrollView
as my main, big view. Inside of it, I have a UIViewController
(not UITableViewController
) which has a UITableView
instance variable, as well as some miscellaneous UIButtons
. I have set the view controller's view frame to CGRectMake(0, 64, 320, 388)
, as I have a tab bar above it (this is not functional yet). At first it works great and looks great, but once I present and dismiss a modalViewController
(thus reloading the UIViewController
, I believe), it pushes the UIViewController
's view to the top of the screen (by default setting it to CGRectMake(0, 0, 320, 460)
, but since I've set wantsFullScreenLayout
to NO
, it now sets it to CGRectMake(0, 0, 320, 388)
.
I've tracked this problem to somewhere between viewWillAppear
and viewDidAppear
. Here are my exact logs after dismissing the modalViewController
:
2011-05-06 11:08:39.974 Campus[1570:207] Frame is 0.000000, 64.000000, 320.000000, 388.000000 (viewWillAppear)
2011-05-06 11:08:40.378 Campus[1570:207] Frame is 0.000000, 0.000000, 320.000000, 388.000000 (viewDidAppear)
As you can see, the frame is fine in viewWillAppear
, but not in viewDidAppear
.
I've done the following things to try to fix it:
- Set the desired frame inloadView
, viewDidLoad
, viewWillAppear
, and viewDidAppear
.
- Set my wants开发者_StackOverflow社区FullScreenLayout
to NO
.
- Killed my [super viewWillAppear:]
and [super viewDidAppear:]
calls in my method overrides.
What should I do?!?!?
My problem here was that, as of iOS 4, Apple only supported 1 view controller per window. However, as of iOS 5, Apple has added support for container view controllers, and has added methods to UIViewController
such as addChildViewController:
. Using the container view controller algorithm solved my problem. Visit the UIViewController Class Reference for more info.
EDIT: for those of you too lazy to search "container view controller" in the class reference, here's the gist of the related section in the class reference:
A custom UIViewController subclass can also act as a container view controller. A container view controller manages the presentation of content of other view controllers it owns, also known as its child view controllers. A child’s view can be presented as-is or in conjunction with views owned by the container view controller.
Your container view controller subclass should declare a public interface to associate its children. The nature of these methods is up to you and depends on the semantics of the container you are creating. You need to decide how many children can be displayed by your view controller at once, when those children are displayed, and where they appear in your view controller’s view hierarchy. Your view controller class defines what relationships, if any, are shared by the children. By establishing a clean public interface for your container, you ensure that children use its capabilities logically, without accessing too many private details about how your container implements the behavior.
Your container view controller must associate a child view controller with itself before adding the child’s root view to the view hierarchy. This allows iOS to properly route events to child view controllers and the views those controllers manage. Likewise, after it removes a child’s root view from its view hierarchy, it should disconnect that child view controller from itself. To make or break these associations, your container calls specific methods defined by the base class. These methods are not intended to be called by clients of your container class; they are to be used only by your container’s implementation to provide the expected containment behavior.
精彩评论