问题描述
问题很简单:如何从 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 中设置文件的所有者.
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.
如果 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.
方法#1:
- (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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!