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

标签 ios uitableview swift

我在 iOS 中制作了一个 TableView ,显示好友(好友)请求列表。对于好友请求单元格,我已将其作为原型(prototype)单元格并为其提供了一个从 UITableViewCell 扩展的自定义类。当我单击单元格上的“接受”按钮时,我想从我拥有的请求数组中删除该行,并将其也从 TableView 中删除。

我考虑过的三个选项是

1) 为自定义单元格提供与表中的行相对应的行属性,因此与请求数组中的行相对应。然后,当调用 accept 时,将该行传递给委托(delegate)函数并调用

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

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

3) 不是传递行值,而是单击“接受”按钮时,在好友列表中搜索用户名,获取找到它的位置的索引,然后使用该索引删除表中的行和 deleteRowsAtIndexPaths。这似乎没问题,特别是因为我永远不会同时收到大量好友请求,而且搜索根本不需要太多时间,但我想如果我可以立即访问行值,它会让事情变得更干净.

代码如下:

View Controller

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

    }
}

委托(delegate)调用的自定义 UITableViewCell 和协议(protocol)

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 属性应该没有问题,然后在点击接受按钮时通知委托(delegate)人。不过,您确实需要调用 reloadData() 来更新受影响的单元格中的引用。

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

关于ios - 如何使用自定义单元格中的按钮获取自定义 UITableViewCell 的行,该按钮将发送到 deleteRowsAtIndexPaths,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30022765/

相关文章:

ios - 使用 CoreGraphics 绘制 unicode 字符串

objective-c - 复选标记代码错误

swift - 在单元测试中运行异步代码的问题

ios - 代码 : Is there a way to search string in expressions defined in breakpoints?

ios - 索引超出范围问题

ios - 从两个单独的 firebase 数据库中加载两个到 tableview swift

ios - 新翻译不会在 iOS 8 中自动显示

ios - 如何自定义 UIInterpolatingMotionEffect 以根据设备的方向设置不同的阴影效果?

ios - 是否可以在 uitableviewcontroller 或 uicollectionviewcontroller 中添加 UIView (Admob)

uitableview - TableView :cellForRowAtIndexPath: in iOS Today Widget with UITableViewController called once