【问题标题】:checkbox button in tableview in SwiftSwift 表格视图中的复选框按钮
【发布时间】:2015-03-13 21:47:25
【问题描述】:

我正在尝试在 tableview 中创建复选框功能。 这是一个待办事项列表,如果按下复选框,单元格将隐藏并在不同部分显示为已完成。

来自 C#,这很容易做到,但在 swift 中,甚至没有一个复选框按钮可以以 :(...

我通过在 IB 中的自定义原型单元格中添加一个带有两个图像(选中、未选中)的按钮来使其工作。 由于您不能在同一个视图控制器/类中声明 tableView 和单元内按钮,因此我必须将 tableViewCell 子类化。

现在,如何从 didSelectRowAtIndexPath 访问复选框?当我选择单元格时,事件会触发,但是当我按下同一单元格中的复选框按钮时,没有任何反应,我无法隐藏单元格。

var indexTag = checkBoxImage.tag
//this is what I have in TableViewCell class

@IBAction func checkBoxInCell(sender: UIButton) {

   checkBoxImage.setImage(UIImage(named:"checked"),forState:UIControlState.Normal)

   if isChecked != false {
        isChecked = false
        cellitemcontent.removeAtIndex(indexTag)
        //can't access the cell from here to update the tableview
   } 
   else {
        isChecked = true
        checkBoxImage.setImage(UIImage(named:"unchecked"),forState:UIControlState.Normal)
    }

}

//this is what I have in my FirstViewController that contains the tableview

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{        
     cellitemcontent.removeAtIndex(indexTag)
     tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
     //when I press the checkBoxImage button in the cell it doesn't fire this event...       
}

【问题讨论】:

标签: swift checkbox tableview tableviewcell


【解决方案1】:

我使用下面的示例代码在单元格中实现复选框按钮(Xcode 7/ Swift 2.0):
-in viewDidLoad {}:(将每个单元格中的复选框状态保存到.plist文件中)

 let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString


    let fnstring = (documentsPath as String)+"/yr-filename.plist"
    let fM = NSFileManager.defaultManager()
    //if (let  a != (fM.fileExistsAtPath(fnstring))) {
    if !(fM.fileExistsAtPath(fnstring)) {
        let onlyarr = NSMutableArray()
        for var i = 0 ; i < 5; ++i{ // number of sections

            var arr = NSArray()
            switch i { // number cell in each section
                case 0: arr = [Int](count: 12, repeatedValue: 0) // 0 means unchecked box.
                case 1: arr =  [Int](count: 13, repeatedValue: 0)
                case 2: arr =  [Int](count: 14, repeatedValue: 0)
                case 3: arr =  [Int](count: 15, repeatedValue: 0)
                case 4: arr =  [Int](count: 16, repeatedValue: 0) 
                default: arr = [Int]()   
            }
            onlyarr.addObject(arr)
            }
            onlyarr.writeToFile(fnstring, atomically: false)  
    }  

- 在覆盖 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { }

let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
    let fnstring = (documentsPath as String)+"/yr-filename.plist"
    let fM = NSFileManager.defaultManager()
    if fM.fileExistsAtPath(fnstring) {
    let chcklstDick = NSMutableArray(contentsOfURL: NSURL(fileURLWithPath: fnstring))
    let chcklstsortedCat: NSArray? = chcklstDick
    let ttt: NSMutableArray = chcklstsortedCat?.objectAtIndex(indexPath.section) as! NSMutableArray
        if ttt.count > 0 {  
            var img = UIImage()
             let j : Int = ttt.objectAtIndex(indexPath.row) as! Int
            NSLog("j: %i", j)
            if j > 0 {
                img = UIImage(named: "checked")!
            }else {
                img = UIImage(named: "unchecked")!
            }
            let bttn : UIButton = UIButton(type: UIButtonType.Custom)
            bttn.frame = CGRectMake(0, 0, img.size.width, img.size.height)
            bttn.setBackgroundImage(img, forState: UIControlState.Normal)
            bttn.addTarget(self, action:"chckBttnTapped:eventy:", forControlEvents: UIControlEvents.TouchUpInside)

            cell.accessoryView = bttn
        }

    }else {NSLog("nonononononononno")}  

- 在 func chckBttnTapped(sender: AnyObject, eventy event: AnyObject) { }

 let touches: NSSet = event.allTouches()!
    let touch: UITouch = touches.anyObject()! as! UITouch
    let crrntTouchPos : CGPoint = touch.locationInView(self.tableView)
    let idxpth: NSIndexPath = self.tableView.indexPathForRowAtPoint(crrntTouchPos)!
   if idxpth.row != NSNotFound {
       self.tableView(self.tableView, accessoryButtonTappedForRowWithIndexPath: idxpth)
    }  

-在 override func tableView(tableView: UITableView, accessoryButtonTappedForRowWithIndexPath indexPath: NSIndexPath) { }

let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
    let fnstring = (documentsPath as String)+"/yr-filename.plist"
    let fM = NSFileManager.defaultManager()
    if fM.fileExistsAtPath(fnstring) {
        let chcklstDick = NSMutableArray(contentsOfURL: NSURL(fileURLWithPath: fnstring))
        let chcklstsortedCat: NSMutableArray? = chcklstDick 
        let ttt: NSMutableArray = chcklstsortedCat?.objectAtIndex(indexPath.section) as! NSMutableArray
        if ttt.count > 0 {
            let j : Int = ttt.objectAtIndex(indexPath.row) as! Int
            var newimg = UIImage()
            if j == 0 {
                newimg = UIImage(named: "checked")!
            }else {
                newimg = UIImage(named: "unchecked")!
            }

             let cell = tableView.dequeueReusableCellWithIdentifier("cellID", forIndexPath: indexPath)
            let bttn : UIButton = UIButton(type: UIButtonType.Custom)
            bttn.frame = CGRectMake(0, 0, newimg.size.width, newimg.size.height)
            bttn.setBackgroundImage(newimg, forState: UIControlState.Normal)

            bttn.addTarget(self, action:"chckBttnTapped:eventy:", forControlEvents: UIControlEvents.TouchUpInside)

            cell.accessoryView = bttn
            self.tableView.reloadData()
            self.tableView.reloadInputViews()
            ttt.replaceObjectAtIndex(indexPath.row, withObject: 1 - j)
            chcklstsortedCat?.replaceObjectAtIndex(indexPath.section, withObject: ttt)
            chcklstsortedCat?.writeToFile(fnstring, atomically: false)
        }
    }  

希望它有用。

【讨论】:

    【解决方案2】:

    我知道你想要完成什么,但我会以不同的方式解决它。也许在您的模型中,您可能有一组待处理的任务,以及另一组已完成的任务。

    节数可以是2。节0和1的行数可以分别是第一个和第二个数组中的元素个数。

    当调用didSelectRowAtIndexPath 时,您可以删除第一个数组中该索引处的项目并将任务添加到第二个数组。然后你必须打电话给tableView.reloadData()

    我知道您只想选择该行并更改其位置,但在 iOS 中,单元格会被重复使用。最好更新数据源,然后重新加载表。

    对于复选标记,您可以确保第 0 节中的项目没有复选标记附件,而第 1 节中的项目有。在单元格出列后,您可以在cellForRowAtIndexPath 中设置附件。

    【讨论】:

    • 嗯,这是一种有趣的方法,但是当我按下该单元格中的复选框按钮时,我仍然无法触发该事件,因为只有实际选择的单元格才会触发它。我还缺少其他细胞事件吗?为什么单元格内的按钮在被选中时不被视为单元格的一部分?
    • 我倾向于将表格视图单元格视为一个通用对象,不知道它包含什么数据。子类 uitableviewcell 并为其添加一个取消按钮。如果您使按钮可访问,那么在 cellforrowatindex 中,您可以设置按钮标签:cell.button.tag = indexPath.row。然后创建一个方法: -(void) buttonTouched: (UIButton *) sender 并在 cellforrowatindex 中设置按钮的目标。因此,当任何一个按钮被点击时,都会调用buttonTouched,你可以通过sender.tag获取行。
    • 换句话说,单元格只知道它在哪一行,而按钮现在也知道,因为标签。
    • 感谢 Josh, - 子类 uitableviewcell 并为其添加一个取消按钮 |Done| - 设置按钮标签:cell.button.tag = indexPath.row |Done| - 创建一个方法:-(void) buttonTouched: (UIButton *) 发送者不确定如何做 - 在 cellforrowatindex 中设置按钮的目标,|Done|。如何创建方法?
    • 对不起... Swift 不客观 -c。 .创建函数 func buttonTouched(sender: UIButton){}
    猜你喜欢
    • 2018-09-22
    • 1970-01-01
    • 2010-11-04
    • 2016-07-10
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    相关资源
    最近更新 更多