如何使用自定义单元格中的按钮来获取自定义UaithitViewCell的行,该按钮将发送到eleterowsatIndE



我在iOS中做了一个表视图,显示了Buddy(friend)请求列表。对于Buddy请求单元,我将其制成了原型单元格,并给了它一个自定义类,该类别从UaithitViewCell延伸。当我单击单元格上的"接受"按钮时,我想从我的请求数组中删除该行,并将其从表视图中删除。

我考虑的三个选项是

1)给自定义单元一个行的属性,该属性与表中的行相对应,因此,请求数组中的行。然后,当调用接受时,将该行传递到委托功能并调用

requests.removeAtIndex(row) 
tableView.reloadData() 

更新所有自定义单元的行属性。此方法有效。但是,这是重新加载表数据的不良习惯(仅从存储的数组重新加载,而不是进行网络请求)

2)将自定义单元格属于行属性,但随后调用

self.requests.removeAtIndex(row)
self.requestsTableView.beginUpdates()
self.requestsTableView.deleteRowsAtIndexPaths([NSIndexPath(forRow:row, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Fade)
self.requestsTableView.endUpdates()

但是,这不会更新已删除的单元格之后的每个单元格中的行值,我要么以某种方式必须全部更新它们,要么调用ReloDdata(),而不是我想做的。

3)而不是传递行值时,单击"接受"按钮时,请在"好友列表中搜索用户名",获取找到位置的索引,然后使用该索引在表中删除表中的行和deleterowsatIndExpaths。这似乎可以做到,尤其是因为我永远不会立即有大量的好友请求,并且搜索根本不需要太多时间,但是我认为如果我可以立即访问该行值,它将使事情变得更加干净。

这是代码:

查看控制器

class RequestsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, RequestTableViewCellDelegate
{
    // Outlet to our table view
    @IBOutlet weak var requestsTableView: UITableView!
    let buddyRequestCellIdentifier: String = "buddyRequestCell"
    // List of buddies who have sent us friend requests
    var requests = [Buddy]()
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func viewDidAppear(animated: Bool) {
        self.getBuddyRequests()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    // MARK: -Table View
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return requests.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: RequestTableViewCell = tableView.dequeueReusableCellWithIdentifier(buddyRequestCellIdentifier) as! RequestTableViewCell
        let buddy = requests[indexPath.row]
        let fullName = "(buddy.firstName) (buddy.lastName)"
        cell.titleLabel?.text = fullName
        cell.buddyUsername = buddy.username
        cell.row = indexPath.row
        cell.delegate = self
        return cell
    }
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let buddy = self.requests[indexPath.row]
    }
    func didAccpetBuddyRequest(row: Int) {
        // Remove buddy at the 'row' index
        // idea 1: update all cells' 'row' value
        //self.requests.removeAtIndex(row)
        // reloading data will reload all the cells so they will all get a new row number
        //self.requestsTableView.reloadData()
        // idea 2
        // Using row doesn't work here becuase these values don't get changed when other cells are added/deleted
        self.requests.removeAtIndex(row)
        self.requestsTableView.beginUpdates()
      self.requestsTableView.deleteRowsAtIndexPaths([NSIndexPath(forRow:row, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Fade)
        self.requestsTableView.endUpdates()
        // idea 3: don't use row, but search for the index by looking for the username
    }
    // MARK: -API
    func getBuddyRequests() {
        // self.requests = array of buddy requests from API request
        self.requestsTableView.reloadData()
    }
}

定制uitaiteViewCell和代表呼叫的协议

protocol RequestTableViewCellDelegate {
    func didAccpetBuddyRequest(row: Int)
}
class RequestTableViewCell: UITableViewCell {
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var acceptButton: UIButton!
    var delegate: RequestTableViewCellDelegate?
    var buddyUsername: String?
    var row: Int?
    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
    }
    @IBAction func touchAccept(sender: AnyObject) {
        // <code goes here to make API request to accept the buddy request>
        self.delegate?.didAccpetBuddyRequest(self.row!)
    }
}

感谢您抽出宝贵的时间阅读此书,感谢您知道在这种情况下对我有帮助的任何帮助/最佳实践。

允许单元格给indexPathdelegate属性,然后何时敲击"接受"按钮时通知委托。但是,您确实需要致电reloadData()来更新受影响的单元格中的引用。

如果您想最大程度地减少重新加载行的数量,请致电reloadRowsAtIndexPaths(),但是我认为创建创建NSIndexPath对象的循环会使您的应用程序慢慢降低。

作为替代方案,我可以另一种建议:

首先在ViewController中将操作方法添加到AcceptButton。在该方法内部,您可以获取包含按钮的单元格的indexpath。这是实施

@IBAction func acceptDidTap(sender: UIButton) {
    let point = tableView.convertPoint(CGPoint.zeroPoint, fromView: button)
    if let indexPath = tableView.indexPathForRowAtPoint(point) {
        // here you got which cell's acceptButton triggered the action
    }
}

最新更新