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

时间:2015-05-04 04:43:47

标签: ios uitableview swift

我在iOS中创建了一个表格视图,显示了好友(好友)请求的列表。对于好友请求单元格,我已经使它成为一个原型单元格,并为它提供了一个从UITableViewCell扩展的自定义类。当我点击"接受"单元格上的按钮,我想从我拥有的请求数组中删除该行,并将其从表视图中删除。

我考虑的三个选项是

1)为自定义单元格赋予与表格中的行对应的行的属性,从而赋予请求数组中的行。然后,当调用accept时,将该行传递给委托函数并调用

requests.removeAtIndex(row) 
tableView.reloadData() 

更新所有自定义单元格'行属性。这种方法有效。但是,这是一个不好的做法,重新加载表数据(它只从存储的数组重新加载,而不是发出网络请求)

2)为自定义单元格赋予row属性,然后调用

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

然而,这不更新删除单元格下面每个单元的行值了,我会以某种方式要么必须全部更新,或致电reloadData(),它ISN'吨是我想做的事情。

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()

    }
}

自定义UITableViewCell和委托调用协议

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!)

    }

}

感谢您抽出宝贵时间阅读本文,感谢您所知道的任何帮助/最佳做法,可以帮助我解决这个问题。

2 个答案:

答案 0 :(得分:0)

为单元格提供indexPathdelegate属性应该没有问题,然后在点击“接受”按钮时通知代理。但是,您需要调用reloadData()来更新受影响的单元格中的引用。

如果您希望最小化重新加载的行数,请改为调用reloadRowsAtIndexPaths(),但我认为创建创建NSIndexPath对象的循环会使您的应用程序速度变慢。

答案 1 :(得分:0)

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

首先在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
    }
}