【问题标题】:UITableview with more than One Custom Cells with Swift带有多个自定义单元格的 UITableview 与 Swift
【发布时间】:2015-08-26 18:53:50
【问题描述】:

我想使用具有不同自定义 tableViewCells 的 UITableview。我的 3 个单元格是这样的:

  • Cell1:应该有一个图像和一个标签。
  • Cell2:应该有两个标签。
  • Cell3:应该有一个dayPicker。

我不想为单元格编写标签。我如何在 Swift 中管理它。我必须为每个单元格编写自己的类吗?我可以使用一个 tableviewController 吗?如何在不同的单元格中填充数据?

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

【问题讨论】:

标签: swift uitableview


【解决方案1】:

我推荐使用这个简单易用的库,我为表格和集合视图制作。您可以根据需要添加任意类型的单元格,并在没有样板代码的情况下实现更干净的 ViewController。

https://github.com/deniskakacka/DKDataSources

对于第一张图片的 UI,您在 ViewController 中的所有代码都是这样的:

lazy var dataSource = DKTableDataSource<CellType>(
    models: [
        DisclosureCellModel(title: "Disclosure 1", action: .action1),
        TextFieldCellModel(title: "TextField 1", placeholder: "Placeholder 1"),
        SwitchCellModel(title: "Switch 1", isOn: true),
        BannerCellModel(imageName: "placeholder"),
        SwitchCellModel(title: "Switch 2", isOn: false),
        BannerCellModel(imageName: "placeholder"),
        DisclosureCellModel(title: "Disclosure 2", action: .action2),
        TextFieldCellModel(title: "TextField 2", placeholder: "Placeholder 2"),
        BannerCellModel(imageName: "placeholder")
    ]
)

// in `viewDidLoad`
dataSource.registerCells(for: tableView)
tableView.dataSource = dataSource

【讨论】:

    【解决方案2】:

    Swift 3.0 + 用最少的代码更新

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

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

    将一个 tableView 拖到您的视图控制器中,向其中添加原型单元格,然后将 UI 元素拖放到您的表格视图单元格中,如果需要,请正确添加约束。

    2。创建自定义UITableViewCell

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

    class FirstTableCell: UITableViewCell {
    }
    
    class SecondTableCell: UITableViewCell {
    }
    
    class ThirdTableCell: UITableViewCell {   
    }
    

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

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

    4.将 UI 元素连接到 swift 代码

    控制拖动表视图并连接到视图控制器类。控制拖动步骤 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.试一试:)

    【讨论】:

    • 太棒了!我喜欢你的动画。
    • 您能告诉我,是否可以为每个单元格添加标题?如果有,怎么做?
    • @PruthviHariharan 如果您想为每个或大部分单元格设置一个“标题”,那么实现标题单元格或部分标题不是一个好主意,这需要更多代码来管理并且会影响表现。我的建议是在原型单元顶部放置一个视图,让它看起来像一个“标题”
    • @FangmingNing 你能用一个小例子解释一下吗。谢谢
    • 如果您使用的是 UITableViewController 而不是 UIViewController,则不需要第 5 步。
    【解决方案3】:

    以上答案是最好的答案,但有很多理由可以解决这个问题。对于遇到此问题的人来说,这是另一个潜在的解决方案:

    我的问题是我正在使用 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)
    

    希望这对某人有所帮助。

    【讨论】:

      【解决方案4】:

      UITableViewController 正在继承 UIViewController,它本身已经映​​射了 UITableviewDataSourceUITableviewDelegate

      您可以继承UITableViewController 或在ViewController 中使用TableView。 之后,您必须实现在UITableviewDataSource 中声明的所需方法(cellForRowAtIndexPathand numberOfRowsInSection)。

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

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

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

      【讨论】:

        【解决方案5】:

        让我先回答你的问题。

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

        我可以使用一个 tableviewController 吗?=> 是的,你可以。但是,您也可以在视图控制器中拥有一个表格视图。

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

        让我举个例子,在 ViewController 中使用 TableView。一旦你理解了主要概念,你就可以尝试任何你想要的修改。

        第 1 步:创建 3 个自定义 TableViewCell。我将它命名为 FirstCustomTableViewCell、SecondCustomTableViewCell、ThirdCustomTableViewCell。您应该使用更有意义的名称。

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

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

        对所有其他人做同样的事情——将他们的自定义类分别设置为“SecondCustomTableViewCell”和“ThirdCustomTableViewCell”。还将标识符连续设置为 secondCustomCell 和 thirdCustomCell。

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

        P.S:您需要将插座放在类定义下。

        所以,在 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()
            }
        }
        

        P.S: 如果你在 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()
            }
        }
        

        【讨论】:

        • 我在 func cellForRowAtIndexPath 中收到消息:“无法将 'UITableViewCell' (0x1dfbfdc) 类型的值转换为 'Projekt.TitelTableViewCell' (0x89568)”。我正在使用 UITableViewController,并且我的自定义单元格“TitelZelle”有一个类“TitelTableViewCell”,我在“TitelZelle”单元格的身份检查器中设置了该类。我该怎么办?
        • 我已将我的手机投射为! TitelTableViewCell 在此单元格中填充我的自定义 UI 元素。
        • 试试这个=> 让 cell = tableView.dequeueReusableCellWithIdentifier("TitelZelle", forIndexPath: indexPath) as TitelTableViewCell
        • @PradipKumar,有什么问题?你的错误是什么?顺便说一句,如果你有任何疑问,你应该问一个问题。作者发布的评论应该有助于理解或澄清关于特定问题的这一点。如果你有问题,你应该去提问并开始你自己的帖子。
        • numberOfRowsInSection 帮助 tableview 确定我们想要多少行。因此,您应该只提供有助于方法确定行数的子句。 indexpath.row == 0 表示您已经有一行,但当时,您的表不知道它是否有一行。所以,你应该这样做。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-30
        • 1970-01-01
        相关资源
        最近更新 更多