交换 UINavigationController 后缺少 UITableView
我已经花了几天时间开发一个简单的 iPhone 应用程序,但还无法理解界面的大部分内容。具体来说,我有一个带有 ImageView 的主菜单视图和几个最终会交换到其他视图的按钮。
除了主菜单之外,我还有一个名为 Browse_Phone 的 UIViewController 子类(它是一个通用应用程序),并且它包含一个名为 tableView 的 UITableView。它最终会连接到数据库,但目前表的内容是硬编码的。以下是 Browse_Phone.m 中的表委托代码(大部分代码借自在线示例):
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
NSString *szCell = [[NSString alloc] initWithFormat: @"Row %i", indexPath.row ];
cell.textLabel.text = szCell;
[szCell release];
// Set up the cell
return cell;
}
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
self.title = @"Browse";
tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
tableView.delegate = self;
tableView.dataSource = self;
self.view = tableView;
}
return self;
}
最后,在主窗口中,有一个按钮可以将主菜单视图替换为导航控制器,该导航控制器使用 Browse_Phone 控制器作为它的 RootViewController (请注意,[发送者超级视图] 是主菜单视图):
- (IBAction)loadBrowse:(id)sender
{
Browse_Phone *browsePhone = [[[Browse_Phone alloc] initWithNibName:nil bundle:nil] autorelease];
if(browsePhone.view)
{
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:browsePhone] autorelease];
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:window cache:YES];
[[sender superview] removeFromSuperview];
[window addSubview:navController.view];
[UIView commitAnimations];
}
}
当我按下按钮时,视图交换似乎可以工作。翻转按预期发生,并且加载了导航控件,但找不到表格。我知道 Browse_Phone 控制器正在被实例化,因为导航栏的标题反映了表格的标题。当我在一个简单的应用程序中使用此代码时,该应用程序刚刚在应用程序委托的 didFinishLaunchingWithOptions 中加载了控制器,它工作得很好。当然,我知道问题很简单,但我错过了。
预先致谢,
瑞安
I've been working on a simple iPhone app for a couple of days now, and haven't been able to wrap my head around quite a bit of the interface. Specifically, I've got a main menu view with an ImageView and a couple of buttons that will eventually swap out to other views.
In addition to the main menu, I've got a UIViewController subclass called Browse_Phone (it's a Universal app), and it contains a UITableView called tableView. It'll eventually be hooked up to a database, but for now, the contents of the table are hard-coded. The following is the table delegate code in Browse_Phone.m (most of this code is borrowed from online examples):
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
NSString *szCell = [[NSString alloc] initWithFormat: @"Row %i", indexPath.row ];
cell.textLabel.text = szCell;
[szCell release];
// Set up the cell
return cell;
}
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
self.title = @"Browse";
tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
tableView.delegate = self;
tableView.dataSource = self;
self.view = tableView;
}
return self;
}
Finally, in the main window, there's a button to swap out the main menu view with a navigation controller that uses a Browse_Phone controller as its RootViewController (note that [sender superview] is the main menu view):
- (IBAction)loadBrowse:(id)sender
{
Browse_Phone *browsePhone = [[[Browse_Phone alloc] initWithNibName:nil bundle:nil] autorelease];
if(browsePhone.view)
{
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:browsePhone] autorelease];
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:window cache:YES];
[[sender superview] removeFromSuperview];
[window addSubview:navController.view];
[UIView commitAnimations];
}
}
When I press the button, the view swap seems to work. The flip occurs as expected, and the navigation control is loaded, but the table is nowhere to be found. I know the Browse_Phone controller is being instantiated, because the navigation bar's title reflects that of the table. When I used this code in a simple app that just loaded the controllers in the app delegate's didFinishLaunchingWithOptions, it worked just fine. Of course, I know the problem is going to be something simple that I've missed.
Thanks in Advance,
Ryan
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是您的
initWithNibName:bundle:
方法。loadView
在initWithNibName:bundle:
之后被调用并覆盖您的视图。您应该在loadView
中加载视图,或者更好的是,在UITableViewController
子类(而不是UIViewController
)中加载视图,并让它为您完成所有操作。It's your
initWithNibName:bundle:
method.loadView
gets called afterinitWithNibName:bundle:
and overrides your view. You should load your view inloadView
, or better yet, subclassUITableViewController
(instead ofUIViewController
) and let it do everything for you.好吧,我想我明白了这个问题;看起来在视图控制器的创建和初始化过程中的某个地方,它们被设置为自动释放,所以当我明确地将它们设置为自动释放时,它们最终会被释放太多次。因此,在表有机会渲染之前,控制器的保留计数会降至 0,并被转储。从 loadBrowse 中每个控制器的初始化中删除自动释放可以解决该问题。我不能说我理解为什么应用程序不会直接崩溃,但问题似乎暂时得到了解决。
All right, I think I understand the problem; it looks like somewhere during the creation and initialization of the view controllers, they're being set to autorelease, so when I explicitly set them to autorelease, they wind up being released one too many times. So before the table gets a chance to render, the controller's retain count drops to 0 and it gets dumped. Removing the autorelease from each controller's initialization in loadBrowse fixes the problem. I can't say I understand why the app doesn't just crash outright, but the problem appears to be solved for the time being.