以编程方式从带有动画的 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,其中dequecustomTableViewCell

在那个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 中删除一行的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式检查带有涟漪动画的Android单选按钮?

如何从 .NET 类中以编程方式访问服务器级 IIS 连接设置?

以编程方式停止 GIF 动画

UITableView 无法从 CustomCell 重新加载数据

如何以编程方式使用 xna 为 fbx 模型设置动画

以编程方式 Swift Segue