在表格视图单元格中使用自定义 XIB

Posted

技术标签:

【中文标题】在表格视图单元格中使用自定义 XIB【英文标题】:Using custom XIB in table view cell 【发布时间】:2018-10-13 16:23:49 【问题描述】:

我已按照本教程创建了一个自定义 .xib,我计划在表格视图的单元格中使用它:

https://medium.com/@brianclouser/swift-3-creating-a-custom-view-from-a-xib-ecdfe5b3a960

这是我创建的 .xib 类:

class UserView: UIView 

    @IBOutlet var view: UIView!
    @IBOutlet weak var username: UILabel!

    override init(frame: CGRect) 
        super.init(frame: frame)
        initialize()
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        initialize()
    

    private func initialize() 
        Bundle.main.loadNibNamed("UserView", owner: self, options: nil)
        addSubview(view)
        view.frame = self.bounds
        view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
    


以前,我在情节提要中创建表格视图单元格,但我开始意识到我想要一个更灵活的视图,以便我可以在我的应用程序的不同部分使用它,所以我创建了上面的自定义 . xib,UserView.

我已更新故事板中的表格视图单元格以使用自定义 .xib:

https://i.stack.imgur.com/t7Tr7.png

这是我的表视图控制器类在创建自定义 .xib 之前的样子(即在情节提要中进行布局):

class UserTableViewController: UITableViewController 

    // MARK: Properties

    let provider = MoyaProvider<ApiService>()
    var users = [User]()

    override func viewDidLoad() 
        super.viewDidLoad()

        tableView.estimatedRowHeight = 100
        tableView.rowHeight = UITableViewAutomaticDimension

        // Fetch the user by their username
        provider.request(.getUsers())  result in
            switch result 
            case let .success(response):
                do 
                    let results = try JSONDecoder().decode(Pagination<[User]>.self, from: response.data)

                    self.users.append(contentsOf: results.data)

                    self.tableView.reloadData()
                 catch 
                    print(error)
                
            case let .failure(error):
                print(error)
                break
            
        
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
    

    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return users.count
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        let cellIdentifier = "UserTableViewCell"

        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? UserTableViewCell  else 
            fatalError("The dequeued cell is not an instance of UserTableViewCell.")
        

        let user = users[indexPath.row]

        cell.username.text = user.username

        return cell
    


这是表格视图单元格类:

class UserTableViewCell: UITableViewCell 

    //MARK: Properties

    @IBOutlet weak var userView: UserView!

    override func awakeFromNib() 
        super.awakeFromNib()
        // Initialization code
    

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

        // Configure the view for the selected state
    


我的问题是,如何更新上面的表格视图控制器类以使用我的自定义 .xib,而不是使用情节提要布局?

【问题讨论】:

UserTableViewCell 的代码在哪里? @Dinsen 添加了课程。 那么你有一个 UserTableViewCell 和 UserView 的自定义 xib 吗? 不,只是 UserView 的自定义 xib,即 UIView 【参考方案1】:

您可以使用两种方式:

创建 UITableViewCell(更好)

1) 将 UIView 改为 UITableViewCell

class CustomTableViewCell: UITableViewCell  

    ...

    class var identifier: String 
        return String(describing: self)
    

2) 注册您的手机

override func viewDidLoad() 
    super.viewDidLoad()

    self.tableView.registerNib(UINib(nibName: CustomTableViewCell.identifier, bundle: nil), forCellReuseIdentifier: CustomTableViewCell.identifier)
    ...

3) 使用 cellForRow(at:)

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier) as! CustomTableViewCell
    cell.username.text = user.username

    return cell

或将视图作为子视图添加到单元格(仅在极少数情况下)

1) 将此添加到 UserView

class UserView: UIView 

    ...

    class func fromNib() -> UserView 
        return UINib(nibName: String(describing: self), bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UserView
    


2) 使用 cellForRow(at:)

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    let cellIdentifier = "UserTableViewCell"

    guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? UserTableViewCell  else 
        fatalError("The dequeued cell is not an instance of UserTableViewCell.")
    

    let userView = UserView.fromNib()
    let user = users[indexPath.row]
    userView.username.text = user.username

    //Use frame size, but for me better to add 4 constraints
    userView.frame = CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight)

    cell.contentView.addSubview(UserView)

    return cell

【讨论】:

如果我将UIView 更改为UITableViewCell,我的故事板的结构会是什么? 另外,我会将我的 xib 的插座连接到我的 UserTableViewCell 还是从情节提要连接到我的 UserTableViewCell UIViewContoller - UITableView - UITableViewCell @IBOutlet 弱变量用户名:UILabel!在xib中连接

以上是关于在表格视图单元格中使用自定义 XIB的主要内容,如果未能解决你的问题,请参考以下文章

如何在表格视图单元格中添加 xib 文件?

在主视图控制器的自定义单元格中使用来自 UIButton 的 IBAction

自定义表格单元格中的堆栈视图

iOS:自定义表格视图单元格中的约束

自定义表格视图单元格中的 UITextField。点击单元格/文本字段时显示选择器视图

来自自定义 Xib 的表格视图中的动态单元格大小 [重复]