问题描述
问题很简单:如何从 Xib 文件加载自定义 UITableViewCell
?这样做允许您使用 Interface Builder 来设计您的单元格.由于内存管理问题,答案显然并不简单.该线程 提到了这个问题并提出了解决方案,但未在 NDA 发布之前代码.这是一个长线程,它讨论了这个问题,但没有提供明确的答案.
The question is simple: How do you load custom UITableViewCell
from Xib files? Doing so allows you to use Interface Builder to design your cells. The answer apparently is not simple due to memory managment issues. This thread mentions the issue and suggests a solution, but is pre NDA-release and lacks code. Here's a long thread that discusses the issue without providing a definitive answer.
这是我使用过的一些代码:
Here's some code I've used:
static NSString *CellIdentifier = @"MyCellIdentifier";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (MyCell *)[nib objectAtIndex:0];
}
要使用此代码,请创建 MyCell.m/.h,这是 UITableViewCell
的新子类,并为所需的组件添加 IBOutlets
.然后创建一个新的空 XIB"文件.在 IB 中打开 Xib 文件,添加一个 UITableViewCell
对象,将其标识符设置为MyCellIdentifier",并将其类设置为 MyCell 并添加您的组件.最后,将 IBOutlets
连接到组件.请注意,我们没有在 IB 中设置 File's Owner.
To use this code, create MyCell.m/.h, a new subclass of UITableViewCell
and add IBOutlets
for the components you want. Then create a new "Empty XIB" file. Open the Xib file in IB, add a UITableViewCell
object, set its identifier to "MyCellIdentifier", and set its class to MyCell and add your components. Finally, connect the IBOutlets
to the components. Note that we did not set the File's Owner in IB.
其他方法提倡设置 File's Owner 并在 Xib 未通过附加工厂类加载时警告内存泄漏.我在 Instruments/Leaks 下测试了上面的内容,没有看到内存泄漏.
Other methods advocate setting the File's Owner and warn of memory leaks if the Xib is not loaded via an additional factory class. I tested the above under Instruments/Leaks and saw no memory leaks.
那么从 Xibs 加载单元格的规范方法是什么?我们是否设置文件的所有者?我们需要工厂吗?如果是这样,工厂的代码是什么样的?如果有多种解决方案,让我们澄清每个解决方案的优缺点......
So what's the canonical way to load cells from Xibs? Do we set File's Owner? Do we need a factory? If so, what's the code for the factory look like? If there are multiple solutions, let's clarify the pros and cons of each of them...
推荐答案
这里有两种方法,原作者声明是IB工程师推荐的.
有关详细信息,请参阅实际帖子.我更喜欢方法#2,因为它看起来更简单.
See the actual post for more details. I prefer method #2 as it seems simpler.
方法一:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
if (cell == nil) {
// Create a temporary UIViewController to instantiate the custom cell.
UIViewController *temporaryController = [[UIViewController alloc] initWithNibName:@"BDCustomCell" bundle:nil];
// Grab a pointer to the custom cell.
cell = (BDCustomCell *)temporaryController.view;
[[cell retain] autorelease];
// Release the temporary UIViewController.
[temporaryController release];
}
return cell;
}
方法#2:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}
return cell;
}
更新(2014 年):方法#2 仍然有效,但不再有相关文档.它曾经在官方文档中,但现在在喜欢故事板.
Update (2014):Method #2 is still valid but there is no documentation for it anymore. It used to be in the official docs but is now removed in favor of storyboards.
我在 Github 上发布了一个工作示例:
https://github.com/bentford/NibTableCellExample
I posted a working example on Github:
https://github.com/bentford/NibTableCellExample
针对 Swift 4.2 进行编辑
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tblContacts.register(UINib(nibName: CellNames.ContactsCell, bundle: nil), forCellReuseIdentifier: MyIdentifier)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MyIdentifier, for: indexPath) as! ContactsCell
return cell
}
这篇关于你如何从 Xib 文件加载自定义 UITableViewCells?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!