带有多个Swift的自定义单元格的UITableview


111

我想将UITableview与其他自定义tableViewCells一起使用。我的3个单元格是这样的:

  • 单元格1:应具有图片和标签。
  • Cell2:应有两个标签。
  • Cell3:应该有一个dayPicker。

我不想为单元格编码。我该如何在Swift中进行管理。我是否必须为每个单元都编写自己的类?我可以使用一个tableviewController吗?如何填充不同单元格中的数据?

我想生成一个tableView,就像iOS设备的联系人应用程序一样。



Answers:


269

首先让我回答您的问题。

我是否必须为每个单元都编写一个自己的类?=>是的,我相信是的。至少,我会那样做。

我可以使用一个tableviewController吗?=>是的,可以。但是,您还可以在View Controller中拥有一个表格视图。

如何填充不同单元格中的数据?=>根据条件,可以在不同的单元格中填充数据。例如,假设您希望前两行像第一种类型的单元格一样。因此,您只需创建/重用第一类单元格并设置其数据即可。我想,当我向您显示屏幕截图时,它将更加清楚。

让我给您一个在ViewController中使用TableView的示例。一旦了解了主要概念,便可以尝试进行任何修改。

步骤1:创建3个自定义TableViewCells。我将其命名为FirstCustomTableViewCell,SecondCustomTableViewCell,ThirdCustomTableViewCell。您应该使用更有意义的名称。

在此处输入图片说明

步骤2:转到Main.storyboard,然后将TableView拖放到View Controller中。现在,选择表视图并转到身份检查器。将“原型单元”设置为3。在这里,您刚刚告诉TableView您可能有3种不同类型的单元。

在此处输入图片说明

步骤3:现在,在TableView中选择第一个单元格,并在身份检查器中,将“ FirstCustomTableViewCell”放在“自定义类”字段中,然后在属性检查器中将标识符设置为“ firstCustomCell”。

在此处输入图片说明

在此处输入图片说明

对其他所有对象执行相同的操作-将其自定义类分别设置为“ SecondCustomTableViewCell”和“ ThirdCustomTableViewCell”。还要连续将标识符设置为secondCustomCell和thirdCustomCell。

步骤4:编辑自定义单元类并根据需要添加插座。我根据您的问题进行了编辑。

PS:您需要将插座放置在类定义之下。

因此,在FirstCustomTableViewCell.swift中,

class FirstCustomTableViewCell: UITableViewCell {

您将放置标签和图像查看插座。

 @IBOutlet weak var myImageView: UIImageView!
 @IBOutlet weak var myLabel: UILabel!

然后在SecondCustomTableViewCell.swift中,添加两个标签,例如-

import UIKit

class SecondCustomTableViewCell: UITableViewCell {

    @IBOutlet weak var myLabel_1: UILabel!
    @IBOutlet weak var myLabel_2: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

和ThirdCustomTableViewCell.swift应该看起来像-

import UIKit

class ThirdCustomTableViewCell: UITableViewCell {

    @IBOutlet weak var dayPicker: UIDatePicker!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

步骤5:在ViewController中,为TableView创建一个Outlet,并从情节提要中设置连接。另外,您需要在类定义中添加UITableViewDelegate和UITableViewDataSource作为协议列表。因此,您的类定义应类似于:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

之后,将表视图的UITableViewDelegate和UITableViewDatasource附加到控制器。此时,您的viewController.swift应该看起来像-

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

PS:如果要在ViewController中使用TableViewController而不是TableView,则可以跳过此步骤。

步骤6:根据Cell类将图像视图和标签拖放到您的单元中。然后从情节提要提供到其出口的连接。

步骤7:现在,在视图控制器中编写UITableViewDatasource的必需方法。

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "firstCustomCell")
            //set the data here
            return cell
        }
        else if indexPath.row == 1 {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "secondCustomCell")
            //set the data here
            return cell
        }
        else {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "thirdCustomCell")
            //set the data here
            return cell
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

1
我收到消息:在func cellForRowAtIndexPath中,“无法将类型'UITableViewCell'(0x1dfbfdc)的值强制转换为'Projekt.TitelTableViewCell'(0x89568)”。我正在使用UITableViewController,并且为我的自定义单元格“ TitelZelle”提供了一个“ TitelTableViewCell”类,该类已在“ TitelZelle”单元格的身份检查器中进行了设置。我需要做什么?
Easyglider

我已经把我的手机投了!TitelTableViewCell可以在此单元格中填充我的自定义UI元素。
Easyglider

7
尝试此=> let cell = tableView.dequeueReusableCellWithIdentifier(“ TitelZelle”,forIndexPath:indexPath)作为TitelTableViewCell
Natasha

2
@PradipKumar,怎么了?你怎么了 顺便说一句,如果您有任何疑问,应该问一个问题。作者发表的评论应该有助于理解或澄清有关特定问题的评论。如果您有问题,应该去提问并发表自己的帖子。
娜塔莎

1
numberOfRowsInSection帮助表格视图确定我们想要的行数。因此,您应该只提供有助于该方法确定行数的子句。indexpath.row == 0意味着您已经有一行,但是那时您的表不知道它是否有一行。因此,您应该这样做。
娜塔莎

32

Swift 3.0 +用最少的代码更新

基本概念: 使用动态单元格原型创建表视图。分配标识符并为每个单元原型创建自定义表格视图单元类。在表视图的委托方法中启动并显示自定义单元格。

1.在情节提要上创建单元格

将tableView拖到您的视图控制器,向其添加原型单元格,然后将UI元素拖放到您的表视图单元格中,并根据需要适当添加约束。

在此处输入图片说明

2.创建自定义UITableViewCell

将以下代码添加到您的项目。我把它放在视图控制器类之上。

class FirstTableCell: UITableViewCell {
}

class SecondTableCell: UITableViewCell {
}

class ThirdTableCell: UITableViewCell {   
}

3.为单元原型分配自定义类和标识符

对于情节提要中的每个单元原型,分配从步骤2创建的自定义类,然后输入唯一的标识符。

在此处输入图片说明

4.将UI元素连接到快速代码

Control拖动表视图并连接到视图控制器类。控件拖动在步骤1中添加到单元原型的UI元素,并连接到相应的表视图单元类。

在此处输入图片说明

5.添加代码以查看控制器并控制表视图

使您的视图控制器符合表视图委托

class YourViewController: UIViewController, UITableViewDataSource, UITableViewDelegate

在中viewDidLoad,设置表视图的委托和数据源。

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.dataSource = self
    self.tableView.delegate = self

}

最后,根据最低要求,添加两个委托方法来控制您的表视图。

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 3
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "firstTableCell") as! FirstTableCell
        // Set up cell.label
        return cell
    } else if indexPath.row == 1 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "secondTableCell") as! SecondTableCell
        // Set up cell.button
        return cell
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "thirdTableCell") as! ThirdTableCell
        // Set up cell.textField
        return cell
    }
}

6.试试看:)

在此处输入图片说明


太棒了!我喜欢你的动画。
iphaaw

您能否告诉我,是否可以为每个单元格放置一个标题?如果是这样,怎么办?
普鲁特维·哈里哈兰(Pruthvi Hariharan)'18年

@PruthviHariharan如果您想为每个或大多数单元格使用一个“标题”,那么实现一个标题单元格或节标题并不是一个好主意,因为这需要更多代码来管理,并且会影响性​​能。我的建议是在原型单元的顶部放置一个视图,使其看起来像“页眉”

@FangmingNing能否请您举一个小例子。谢谢
Pruthvi Hariharan

如果您使用的是UITableViewController而不是UIViewController,则不需要步骤5。
迪帕克塔库尔

0

上面的答案是最好的答案,但是有很多原因可以解决此问题。对于有此问题的任何人,这是另一个潜在的解决方案:

我的问题是我在选择ViewController类而不是情节提要视图。因此,由于未使用情节提要,因此我对情节提要单元的引用毫无意义。

我正在这样做:

let viewControllerB = SubViewController()
viewControllerB.passedData = diseases[indexPath.row].name
navigationController?.pushViewController(viewControllerB, animated: true)

我需要做这样的事情:

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "SubViewStoryboardController") as! SubViewController
nextViewController.passedData = diseases[indexPath.row].name
self.present(nextViewController, animated:true, completion:nil)

希望这对某人有帮助。


-22

UITableViewController正在继承UIViewController已经具有UITableviewDataSourceUITableviewDelegate映射到其自身的对象。

您可能会继承UITableViewController或使用TableView内部对象ViewController。之后,您必须实现cellForRowAtIndexPath and numberOfRowsInSection在中声明的必需方法()UITableviewDataSource

同样在情节提要中,您需要创建具有唯一ID的单元原型。

单元格有一些基本类型,例如(标题,副标题)-如果不需要特殊配置,也可以使用它们。

因此,对于选择器,是的,您需要创建自己的自定义单元。创建必要的自定义UITableViewCell类保存日期选择器,并确保使用委托将所需的结果发送回给您ViewController

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.