我在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!)
}
}
感谢您抽出宝贵时间阅读本文,感谢您所知道的任何帮助/最佳做法,可以帮助我解决这个问题。
答案 0 :(得分:0)
为单元格提供indexPath
和delegate
属性应该没有问题,然后在点击“接受”按钮时通知代理。但是,您需要调用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
}
}