使用自定义函数删除 tableview 单元格

Posted

技术标签:

【中文标题】使用自定义函数删除 tableview 单元格【英文标题】:Delete tableview cell with a custom fuction 【发布时间】:2016-05-10 19:09:39 【问题描述】:

我创建了一个名为 toDoItemDeleted 的自定义删除函数,但似乎有错误

.

.

知道如何解决吗?(我关注这个tutorial)

表格视图

    class TodolistTable: UITableViewController , TableViewCellDelegate   

var todoItems: [DataSource] = []

override func viewDidLoad() 
    self.tableView.reloadData()
   tableView.backgroundView = UIImageView(image: UIImage(named: "backgroundTableView"))

    tableView.dataSource = self
    tableView.delegate = self
    tableView.registerClass(TableViewCell.self, forCellReuseIdentifier: "Cell")
    tableView.separatorStyle = .None
    tableView.backgroundColor = UIColor.blackColor()
    tableView.rowHeight = 50;

    

override func viewWillAppear(animated: Bool) 
    self.tableView.reloadData()

     




@IBAction func unwinTodlist (segue: UIStoryboardSegue)

    let source = segue.sourceViewController as! ViewController
    let todoItemx : DataSource = source.todoitemer

    if todoItemx.itenName != ""  

    self.todoItems.append(todoItemx)

    self.tableView.reloadData()
    



    

override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    return todoItems.count    

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return 1
      


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    let TempCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
        as! TableViewCell



    let todoItem = todoItems[indexPath.row]


    //TempCell.textLabel?.backgroundColor = UIColor.clearColor()
    TempCell.selectionStyle = .None
    TempCell.textLabel?.text = todoItem.itenName
    TempCell.delegate = self
    TempCell.Item = todoItem

    return TempCell
    



override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 

    tableView.deselectRowAtIndexPath(indexPath, animated: false)

    let tappedItem = todoItems [indexPath.row] as DataSource
    tappedItem.completed = !tappedItem.completed
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation:UITableViewRowAnimation.None)

    

override func tableView(tableView: UITableView, heightForRowAtIndexPath
    indexPath: NSIndexPath) -> CGFloat 
    return tableView.rowHeight;
   



func toDoItemDeleted(Item2: DataSource) 
    // could use this to get index when Swift Array indexOfObject works
    // let index = toDoItems.indexOfObject(toDoItem)
    // in the meantime, scan the array to find index of item to delete
    let index = (todoItems as NSArray).indexOfObject(Item2)
    if index == NSNotFoundreturn
    // could removeAtIndex in the loop but keep it here for when indexOfObject works
    todoItems.removeAtIndex(index)

    // use the UITableView to animate the removal of this row
    tableView.beginUpdates()
    let indexPathForRow = NSIndexPath(forRow: index, inSection: 0)
    tableView.deleteRowsAtIndexPaths([indexPathForRow], withRowAnimation: .Fade)
    tableView.endUpdates()
    

// MARK: - Table view delegate

func colorForIndex(index: Int) -> UIColor 
    let itemCount = todoItems.count - 1
    let val = (CGFloat(index) / CGFloat(itemCount)) * 0.6
    return UIColor(red: 1.0, green: val, blue: 0.0, alpha: 1.0)
    

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
               forRowAtIndexPath indexPath: NSIndexPath) 
    cell.backgroundColor = colorForIndex(indexPath.row)
    

    

tableviewCell

      import UIKit
      import QuartzCore


        // A protocol that the TableViewCell uses to inform its delegate of state change
      protocol TableViewCellDelegate 
// indicates that the given item has been deleted
func toDoItemDeleted(todoItem: DataSource)
     

      class TableViewCell: UITableViewCell 

      let gradientLayer = CAGradientLayer()
      var originalCenter = CGPoint()
      var deleteOnDragRelease = false, completeOnDragRelease = false
      var tickLabel: UILabel, crossLabel: UILabel
      let label: StrikeThroughText
      var itemCompleteLayer = CALayer()
      // The object that acts as delegate for this cell.
      var delegate: TableViewCellDelegate?
      // The item that this cell renders.
      var Item: DataSource? 
      didSet 
        //label.text = Item!.text
        label.strikeThrough = Item!.completed
        itemCompleteLayer.hidden = !label.strikeThrough
       
       

    required init(coder aDecoder: NSCoder) 
    fatalError("NSCoding not supported")
        

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) 
    // create a label that renders the to-do item text
    label = StrikeThroughText(frame: CGRect.null)
    label.textColor = UIColor.whiteColor()
    label.font = UIFont.boldSystemFontOfSize(16)
    label.backgroundColor = UIColor.clearColor()

    // utility method for creating the contextual cues
    func createCueLabel() -> UILabel 
        let label = UILabel(frame: CGRect.null)
        label.textColor = UIColor.whiteColor()
        label.font = UIFont.boldSystemFontOfSize(32.0)
        label.backgroundColor = UIColor.clearColor()
        return label
    

    // tick and cross labels for context cues
    tickLabel = createCueLabel()
    tickLabel.text = "\u2713"
    tickLabel.textAlignment = .Right
    crossLabel = createCueLabel()
    crossLabel.text = "\u2717"
    crossLabel.textAlignment = .Left

    super.init(style: style, reuseIdentifier: reuseIdentifier)

    addSubview(label)
    addSubview(tickLabel)
    addSubview(crossLabel)
    // remove the default blue highlight for selected cells
    selectionStyle = .None

    // gradient layer for cell
    gradientLayer.frame = bounds
    let color1 = UIColor(white: 1.0, alpha: 0.2).CGColor as CGColorRef
    let color2 = UIColor(white: 1.0, alpha: 0.1).CGColor as CGColorRef
    let color3 = UIColor.clearColor().CGColor as CGColorRef
    let color4 = UIColor(white: 0.0, alpha: 0.1).CGColor as CGColorRef
    gradientLayer.colors = [color1, color2, color3, color4]
    gradientLayer.locations = [0.0, 0.01, 0.95, 1.0]
    layer.insertSublayer(gradientLayer, atIndex: 0)

    // add a layer that renders a green background when an item is complete
    itemCompleteLayer = CALayer(layer: layer)
    itemCompleteLayer.backgroundColor = UIColor(red: 0.0, green: 0.6, blue: 0.0, alpha: 1.0).CGColor
    itemCompleteLayer.hidden = true
    layer.insertSublayer(itemCompleteLayer, atIndex: 0)

    // add a pan recognizer
    let recognizer = UIPanGestureRecognizer(target: self, action:   #selector(TableViewCell.handlePan(_:)))
    recognizer.delegate = self
    addGestureRecognizer(recognizer)
      

     let kLabelLeftMargin: CGFloat = 15.0
     let kUICuesMargin: CGFloat = 10.0, kUICuesWidth: CGFloat = 50.0
     override func layoutSubviews() 
    super.layoutSubviews()
    // ensure the gradient layer occupies the full bounds
    gradientLayer.frame = bounds
    itemCompleteLayer.frame = bounds
    label.frame = CGRect(x: kLabelLeftMargin, y: 0,
                         width: bounds.size.width - kLabelLeftMargin,  height: bounds.size.height)
    tickLabel.frame = CGRect(x: -kUICuesWidth - kUICuesMargin, y: 0,
                             width: kUICuesWidth, height: bounds.size.height)
    crossLabel.frame = CGRect(x: bounds.size.width + kUICuesMargin, y: 0,
                              width: kUICuesWidth, height: bounds.size.height)


     //MARK: - horizontal pan gesture methods
      func handlePan(recognizer: UIPanGestureRecognizer) 
    // 1
    if recognizer.state == .Began 
        // when the gesture begins, record the current center location
        originalCenter = center
    
    // 2
     if recognizer.state == .Changed 
        let translation = recognizer.translationInView(self)
        center = CGPointMake(originalCenter.x + translation.x,  originalCenter.y)
        // has the user dragged the item far enough to initiate a delete/complete?
        deleteOnDragRelease = frame.origin.x < -frame.size.width / 2.0
        completeOnDragRelease = frame.origin.x > frame.size.width / 2.0
        // fade the contextual clues
        let cueAlpha = fabs(frame.origin.x) / (frame.size.width / 2.0)
        tickLabel.alpha = cueAlpha
        crossLabel.alpha = cueAlpha
        // indicate when the user has pulled the item far enough to invoke the given action
        tickLabel.textColor = completeOnDragRelease ? UIColor.greenColor() : UIColor.whiteColor()
        crossLabel.textColor = deleteOnDragRelease ? UIColor.redColor() : UIColor.whiteColor()
    
    // 3
    if recognizer.state == .Ended 
        let originalFrame = CGRect(x: 0, y: frame.origin.y,
                                   width: bounds.size.width, height: bounds.size.height)
        if deleteOnDragRelease 
            if delegate != nil && Item != nil 
                // notify the delegate that this item should be deleted
                delegate!.toDoItemDeleted(Item!)
            
         else if completeOnDragRelease 
            if Item != nil 
                Item!.completed = true
            
            label.strikeThrough = true
            itemCompleteLayer.hidden = false
            UIView.animateWithDuration(0.2, animations: self.frame = originalFrame)
         else 
            UIView.animateWithDuration(0.2, animations: self.frame = originalFrame)
        
    


 override func gestureRecognizerShouldBegin(gestureRecognizer:    UIGestureRecognizer) -> Bool 
    if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer 
        let translation = panGestureRecognizer.translationInView(superview!)
        if fabs(translation.x) > fabs(translation.y) 
            return true
        
        return false
      
    return false
     
     

【问题讨论】:

【参考方案1】:

不要使用 UIGestureRecognizer。您可以轻松创建删除操作:

override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool 
    return true


override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 
    if editingStyle == .Delete 
        // delete object
    

【讨论】:

是的,我知道,但我想实现这种类型的删除 raywenderlich.com/77974/… @NgomaMbakuDavy 尝试看看这个:github.com/MortimerGoro/MGSwipeTableCell 它与您正在做的类似

以上是关于使用自定义函数删除 tableview 单元格的主要内容,如果未能解决你的问题,请参考以下文章

添加另一个部分时将编辑的文本保留在自定义单元格中([tableView 刷新数据])

无法从自定义表格视图单元格按钮中删除行

以编程方式加载自定义子视图,就像它们是单元格一样?

如何在自定义滑动(而不是滑动删除)单元格(滑动到邮件/短信)中点击一个单元格时删除在其他 TableView 单元格中添加的子视图

TableView,自定义单元格编辑行为

从自定义 tableView 单元格文本字段中获取数据