为了账号安全,请及时绑定邮箱和手机立即绑定

如何从XIB文件加载自定义UITableViewCells?

如何从XIB文件加载自定义UITableViewCells?

慕标琳琳 2019-07-04 18:32:58
如何从XIB文件加载自定义UITableViewCells?问题很简单:如何加载自定义UITableViewCell从XIB文件?这样做可以让您使用InterfaceBuilder来设计单元格。显然,由于内存管理问题,答案并不简单。这条线提到了这个问题,并提出了解决方案,但在NDA发布之前,缺乏代码。这是一个长螺纹这讨论了这个问题,但没有给出明确的答案。下面是我使用过的一些代码: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中设置文件的所有者。其他方法主张设置文件所有者,并警告如果XIB未通过额外的工厂类加载,则会发生内存泄漏。我在“仪器/泄漏”下测试了上面的内容,没有发现内存泄漏。那么,从XBS加载电池的标准方法是什么呢?我们设置了文件的所有者吗?我们需要工厂吗?如果是的话,工厂的代码是什么样子的?如果有多种解决方案,让我们澄清每一个方案的利弊.
查看完整描述

3 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

正确的解决办法是:

- (void)viewDidLoad{
    [super viewDidLoad];
    UINib *nib = [UINib nibWithNibName:@"ItemCell" bundle:nil];
    [[self tableView] registerNib:nib forCellReuseIdentifier:@"ItemCell"];}-(UITableViewCell *)tableView:(UITableView *)tableView 
    cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    // Create an instance of ItemCell
    PointsItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ItemCell"];

    return cell;}


查看完整回答
反对 回复 2019-07-04
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

寄存器

在iOS 7之后,这个过程被简化为(SWIFT 3.0):

// For registering nib filestableView.register(UINib(nibName: "MyCell", bundle: Bundle.main), forCellReuseIdentifier: "cell")
// For registering classestableView.register(MyCellClass.self, forCellReuseIdentifier: "cell")

()也可以通过在.xib.stroyboard文件,作为原型单元格。如果需要将类附加到它们,可以选择单元格原型并添加相应的类(必须是UITableViewCell当然)。

去队列

然后,使用(SWIFT 3.0):

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
    let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.textLabel?.text = "Hello"

    return cell}

不同之处在于,这个新方法不仅将单元格排出队列,还会创建不存在的情况(这意味着您不必这样做)。if (cell == nil),该单元格已准备好使用,如上面的示例所示。

(警告tableView.dequeueReusableCell(withIdentifier:for:)有新的行为,如果你调用另一个(没有indexPath:)你得到了旧的行为,在这种行为中你需要检查nil如果你自己动手的话,注意到UITableViewCell?返回值

if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? MyCellClass{
    // Cell be casted properly
    cell.myCustomProperty = true}else{
    // Wrong type? Wrong identifier?}

当然,单元格的关联类的类型是您在.xib文件中为UITableViewCell子类,或者使用其他寄存器方法。

配置

理想情况下,您的单元格在注册时已经在外观和内容定位(如标签和图像视图)和cellForRowAtIndexPath方法只需填写它们。

合在一起

class MyCell : UITableViewCell{
    // Can be either created manually, or loaded from a nib with prototypes
    @IBOutlet weak var labelSomething : UILabel? = nil}class MasterViewController: UITableViewController {
    var data = ["Hello", "World", "Kinda", "Cliche", "Though"]

    // Register
    override func viewDidLoad()
    {
        super.viewDidLoad()

        tableView.register(MyCell.self, forCellReuseIdentifier: "mycell")
        // or the nib alternative
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return data.count    }

    // Dequeue
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "mycell", for: indexPath) as! MyCell

        cell.labelSomething?.text = data[indexPath.row]

        return cell    }}

当然,这在objc中都有相同的名称。


查看完整回答
反对 回复 2019-07-04
  • 3 回答
  • 0 关注
  • 740 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信