以编程方式从带有动画的 customCell 类中的 tableView 中删除一行
Posted
技术标签:
【中文标题】以编程方式从带有动画的 customCell 类中的 tableView 中删除一行【英文标题】:Programmatically delete a row from tableView from its customCell class with animation 【发布时间】:2016-09-03 15:06:22 【问题描述】:目标
从customTableViewCell
调用的TableView中删除一行
我的CustomTableViewController
中有一个tableView
,其中deque 是customTableViewCell
。
在那个customTableViewCell
类中,我有一个UIButton
操作,它需要在按下时更改其按钮标题,并在需要时删除行本身。为此,我将该单元格的 indexPath 传递给该@中的 globalVariable 987654327@ 类,我用它来删除我通过CustomTableViewController
的实例访问的行。
代码
retrieving
来自 firebase 的数据库和 struct
的代码是不必要的,仅供参考。
CustomTableViewController
其中嵌入了tableView
:-
class FriendsListController: UIViewController , UITableViewDelegate , UITableViewDataSource,addingFriendDelegate
var profileFeed = [profileStruct]() //profileFeed is the an array of type struct, in which i am storing my retrieved database value's
var customCellHandler = FriendsTableViewCell()
override func viewDidLoad()
super.viewDidLoad()
listTableView.delegate = self
listTableView.dataSource = self
customCellHandler.delegate = self
if friendListTable == true && profileFeed.isEmpty == true
FIRControllerHandle.retrievingForTheFriendListTableView (userName, lctn, ID) in
let temp = profileStruct.init(userName: userName, location: lctn, UID: ID)
self.profileFeed.insert(temp, atIndex: 0)
self.listTableView.reloadData()
self.presentViews()
else if friendListTable == false && profileFeed.isEmpty == true
print(profileFeed)
print(profileFeed.isEmpty)
FIRControllerHandle.retrievingForThePendingFriendRequests( (userName, location, userId) in
if self.profileFeed.isEmpty == true
let temp = profileStruct.init(userName: userName, location: location, UID: userId)
self.profileFeed.insert(temp, atIndex: 0)
self.listTableView.reloadData()
self.presentViews()
)
//Code for storing the data in a struct is just for reference , trivial w.r.t context of my question
//addindFriendDelegate methods
func deleteRowAtTheIndex(index: NSIndexPath)
listTableView.deleteRowsAtIndexPaths([index], withRowAnimation: .Fade)
//TableView delegate Functions.
func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 1
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return profileFeed.count
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = listTableView.dequeueReusableCellWithIdentifier("friendsCell") as! FriendsTableViewCell
cell.userNameLabel.text = profileFeed[indexPath.row].profileName
cell.userUID = profileFeed[indexPath.row].profileUserId
cell.userName = profileFeed[indexPath.row].profileName
cell.userLocationLabel.text = profileFeed[indexPath.row].profileLocation
cell.currentUserName = currentuserName_initial
cell.friendsListBool = friendListTable
cell.cellIndexPath = indexPath //Sending the indexPath of that row
return cell
customTableViewCell
响应按钮操作的类:-
protocol addingFriendDelegate
func deleteRowAtTheIndex(index: NSIndexPath)
class FriendsTableViewCell: UITableViewCell
var userName : String!
var userLocation : String!
var userUID : String!
var FIRControllerHandle : FIRController = FIRController() //I am using firebase as my backend and `FIRController` class handles all the firebase functions.
var delegate: addingFriendDelegate!
var friendsListBool : Bool = true // I am managing two tableViews datasource in one tableView , and `friendsListBool` tells me which node to retrieve from my database.
var currentUserName : String!
var cellIndexPath : NSIndexPath!
var listTableViewController : FriendsListController = FriendsListController() // Instance of viewController in which my tableView is embed
@IBAction func addFriendsBtnAction(sender: CustomButton)
if friendsListBool
FIRControllerHandle.sendFriendRequest(userUID, completionBlock:
self.addFriendsBtn.setTitle("Sent", forState: .Normal) //Setting the title
print(self.cellIndexPath.row) //Printing Fine
self.listTableViewController.listTableView.deleteRowsAtIndexPaths([self.cellIndexPath], withRowAnimation: .Fade)
)
else if !friendsListBool
FIRControllerHandle.accepFriendRequest(currentUserName, friendID: userUID, friendName : userName ,completionBlock:
self.addFriendsBtn.setTitle("Friends", forState: .Normal)
)
我做了什么
self.listTableViewController.listTableView.deleteRowsAtIndexPaths([self.cellIndexPath], withRowAnimation: .Fade)
在@IBAction func addFriendsBtnAction(sender: CustomButton)
中调用,其中listTableViewController
是嵌入了我的tableView 的viewController 实例,cellIndexPath
我要删除的行的indexPath
错误线
self.listTableViewController.listTableView.deleteRowsAtIndexPaths([self.cellIndexPath], withRowAnimation: .Fade)
错误:- 致命错误:在展开可选值时意外发现 nil
(lldb)
PS:- 我不是特别倾向于 protocol-delegate
方法。我正在寻找替代方法。
【问题讨论】:
【参考方案1】:从不使用FriendsListController()
等默认初始化程序初始化视图控制器。
它将创建一个全新的实例,这不是您在视图层次结构中期望的实例。
协议/委托的合适替代方案是完成闭包。
根据您的最新代码更改以下内容:
删除
var customCellHandler = FriendsTableViewCell()
var delegate: addingFriendDelegate!
插入cellForRowAtIndexPath
cell.delegate = self
插入deleteRowAtTheIndex
profileFeed.removeAtIndex(index.row)
【讨论】:
但是protocol / delegate
会比completion closure.
更好吗?还有我用来删除行的代码行,它可以正常工作吗..?感谢您的输入顺便说一句:)
在我个人看来,闭包比协议/委托要好得多(也更容易)。实际上,您应该避免咬住喂您的手,这意味着不要将删除对象的代码放在对象本身中。这是控制器的业务,而不是视图。
同样的问题:FriendsTableViewCell()
不是您期望的(单个)单元格。一个表格视图可以有几十个(不同的)表格视图单元格。请尝试了解表格视图的工作原理。
PS:如果您只在(表)视图中删除项目而不在模型(数据源)中删除项目,您将遇到下一个致命问题。
使用代码最简单的方法是删除var customCellHandler = FriendsTableViewCell()
和customCellHandler.delegate = self
行,并在cellForRowAtIndexPath
中插入cell.delegate = self
。在委托方法deleteRowAtTheIndex
中进一步插入profileFeed.removeAtIndex(index.row)
以上是关于以编程方式从带有动画的 customCell 类中的 tableView 中删除一行的主要内容,如果未能解决你的问题,请参考以下文章
如何从 .NET 类中以编程方式访问服务器级 IIS 连接设置?