Her*_*eis 2 uitableview ios swift swift-protocols swift3
仍然是一个 Swift 菜鸟,我一直在寻找一种正确的方法/最佳实践来管理我的UITableView(使用自定义UserCells)中的行删除,基于在using 委托中点击 a UIButton,UserCell这似乎是最干净的方法。
我跟着这个例子:UITableViewCell Buttons with action
我拥有的
UserCell 类
protocol UserCellDelegate {
func didPressButton(_ tag: Int)
}
class UserCell: UITableViewCell {
var delegate: UserCellDelegate?
let addButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Add +", for: .normal)
button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
addSubview(addButton)
addButton.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -6).isActive = true
addButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
addButton.heightAnchor.constraint(equalToConstant: self.frame.height / 2).isActive = true
addButton.widthAnchor.constraint(equalToConstant: self.frame.width / 6).isActive = true
}
func buttonPressed(_ sender: UIButton) {
delegate?.didPressButton(sender.tag)
}
}
Run Code Online (Sandbox Code Playgroud)
TableViewController 类:
class AddFriendsScreenController: UITableViewController, UserCellDelegate {
let cellId = "cellId"
var users = [User]()
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCell
cell.delegate = self
cell.tag = indexPath.row
return cell
}
func didPressButton(_ tag: Int) {
let indexPath = IndexPath(row: tag, section: 0)
users.remove(at: tag)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
Run Code Online (Sandbox Code Playgroud)
其中Users 在users视图控制器中附加了对数据库的调用。
我的问题
indexPath更新并且不会超出范围吗?即,如果在索引 0 处删除一行,删除索引 0 处的“新”行会正常工作还是会删除索引 1 处的行?我想要的是
能够单击表格每一行中的按钮,这会将其从表格视图中删除。
我一定是得到了一些相当基本的错误,如果一个 Swift 骑士能启发我,我真的很感激。
提前谢谢了。
您的代码中至少有 3 个问题:
UserCell你应该调用:button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
Run Code Online (Sandbox Code Playgroud)
一旦你的单元被实例化(比如,从你的实现中init(style:reuseIdentifier:)),那么它self指的是UserCell.
AddFriendsScreenController'stableView(_:cellForRowAt:)您正在设置单元格本身的标签 ( cell.tag = indexPath.row) 但在您的UserCell'sbuttonPressed(_:)您正在使用按钮的标签。您应该将该函数修改为:func buttonPressed(_ sender: UIButton) {
//delegate?.didPressButton(sender.tag)
delegate?.didPressButton(self.tag)
}
Run Code Online (Sandbox Code Playgroud)
indexPaths。理想情况下,您应该避免依赖索引路径来识别单元格,但这是另一个主题。 编辑:
避免标签与索引路径不同步的一个简单解决方案是将每个单元格与User它们应该表示的对象相关联:
user向您的UserCell类添加一个属性:class UserCell: UITableViewCell {
var user = User() // default with a dummy user
/* (...) */
}
Run Code Online (Sandbox Code Playgroud)
User从内部将此属性设置为正确的对象tableView(_:cellForRowAt:)://cell.tag = indexPath.row
cell.user = self.users[indexPath.row]
Run Code Online (Sandbox Code Playgroud)
UserCellDelegate协议方法的签名以传递user存储在单元格中的属性而不是它的tag:protocol UserCellDelegate {
//func didPressButton(_ tag: Int)
func didPressButtonFor(_ user: User)
}
Run Code Online (Sandbox Code Playgroud)
UserCell的buttonPressed(_:)相应动作:func buttonPressed(_ sender: UIButton) {
//delegate?.didPressButton(sender.tag)
//delegate?.didPressButton(self.tag)
delegate?.didPressButtonFor(self.user)
}
Run Code Online (Sandbox Code Playgroud)
AddFriendsScreenController,根据User数据源中的位置确定要删除的正确行://func didPressButton(_ tag: Int) { /* (...) */ } // Scrap this.
func didPressButtonFor(_ user: User) {
if let index = users.index(where: { $0 === user }) {
let indexPath = IndexPath(row: index, section: 0)
users.remove(at: index)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
Run Code Online (Sandbox Code Playgroud)
注意if let index = ...构造(可选绑定)和三元组===(身份运算符)。
这种方法的缺点是它会在您的类User和UserCell类之间创建紧密耦合。例如,最佳实践会规定使用更复杂的MVVM 模式,但这确实是另一个主题......
| 归档时间: |
|
| 查看次数: |
6849 次 |
| 最近记录: |