General Description:
首先,我有一个UITableView
,它已被放置到使用Interface Builder生成的Xcode视图中.视图的文件所有者设置为Xcode生成的UIViewController
子类.在这个子类中,我添加了numberOfSectionsInTableView: tableView:numberOfRowsInSection:
和tableView:cellForRowAtIndexPath:
的工作实现,表视图的dataSource
和delegate
通过Interface Builder中的文件所有者连接到这个类.
以上配置工作正常.当我想将这个表视图的dataSource
和delegate
实现移出到一个单独的类中时,就会出现这个问题,很可能是因为除了表视图之外,视图上还有其他控件,我想将与表视图相关的代码移出到它自己的类中.为了实现这一点,我try 以下方法:
- 在Xcode中创建一个
UITableViewController
的新子类 - Move the known-good implementations of
numberOfSectionsInTableView:
,tableView:numberOfRowsInSection:
和tableView:cellForRowAtIndexPath:
to the new subclass - 将
UITableViewController
拖动到InterfaceBuilder中existing XIB的顶层,删除为该UITableViewController
自动创建的UIView
/UITableView
,然后将UITableViewController
的类设置为与新子类匹配 - Remove the previously-working
UITableView
's existingdataSource
和delegate
connections 和 connect them to the newUITableViewController
完成后,我没有一个工作UITableView
.我最终得到了三种结果中的一种,这三种结果似乎是随机发生的:
- 加载
UITableView
后,我会收到一个运行时错误,表明我正在向一个无法识别它的对象发送tableView:cellForRowAtIndexPath:
- 在没有错误的情况下加载到调试器时
- 没有错误,但
UITableView
没有出现
经过一些调试,并创建了一个基本项目来重现这个问题,我通常会看到上面的第三个选项(没有错误,但没有可见的表视图).我添加了一些NSLog调用,发现虽然numberOfSectionsInTableView:
和numberOfRowsInSection:
都被调用,但cellForRowAtIndexPath:
没有.我确信我错过了一些非常简单的事情,并希望答案对比我更有经验的人来说可能是显而易见的.如果这不是一个简单的答案,我很乐意用一些代码或示例项目进行更新.谢谢你抽出时间!
Complete steps to reproduce:
- Create a new iPhone OS, View-Based Application in Xcode 和 call it
TableTest
- Open
TableTestViewController.xib
in Interface Builder 和 drag aUITableView
onto the provided view surface. - Connect the
UITableView
'sdataSource
和delegate
-outlets to File's Owner, which should already represent theTableTestViewController
-class. Save your changes - 回到Xcode,将以下代码添加到
TableTestViewController.m:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(@"Returning num sections");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@"Returning num rows");
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Trying to return cell");
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
cell.text = @"Hello";
NSLog(@"Returning cell");
return cell;
}
构建并运行,你会看到单词
Hello
出现在UITableView
中现在,为了try 将
UITableView
的逻辑转移到一个单独的类中,首先在Xcode中创建一个新文件, SelectUITableViewController
子类并调用TableTestTableViewController
类- Remove the above code snippet from
TableTestViewController.m
和 place it intoTableTestTableViewController.m
, replacing the default implementation of these three methods with ours. - Back in Interface Builder within the same
TableTestViewController.xib
-file, drag aUITableViewController
into the main IB window 和 delete the newUITableView
object that automatically came with it - 将这个新的
UITableViewController
级设置为TableTestTableViewController
级 - Remove the
dataSource
和delegate
bindings from the existing, previously-workingUITableView
和 reconnect the same two bindings to the newTableTestTableViewController
we created. - Save changes, Build 和 Go, 和 if you're getting the results I'm getting, note the
UITableView
no longer functions properly
Solution:
#import "TableTestTableViewController.h"
和
IBOutlet TableTestTableViewController *myTableViewController;
Then, in Interface Builder, connect the new outlet from File's Owner to TableTestTableViewController
in the main IB window. No changes are necessary in the UI part of the XIB. Simply having this outlet in place, even though no user code directly uses it, resolves the problem completely. Thanks to those who've helped 和 credit goes to BaldEagle on the iPhone Developer Forums for finding the solution.