【问题标题】:Swift: Change button image in table view on clickSwift:单击时更改表格视图中的按钮图像
【发布时间】:2015-02-09 21:58:02
【问题描述】:

我使用 Swift 为 iPhone 创建了一个 Xcode 项目,后端使用 Parse。我目前的问题是将待办事项列表应用程序创建为大型应用程序的一个选项卡。

在自定义原型单元格内部,我想要一个复选框按钮,当单击该按钮时会更改其图像以及更改该单元格的 isChecked:Bool 变量。我已经完成了大部分工作,但是在设置和访问此按钮的适当变量方面遇到了障碍。

编辑:感谢下面的答案和其他资源,我终于为这个复选框功能编写了工作代码。本质上,按钮的标记属性设置为等于 PFObject 的 indexPath.row。由于我最初的问题有点宽泛,我正在更新下面的代码,以便它可以帮助其他正在开发类似功能的新开发人员。可能有更好的方法,但这似乎有效。

//TasksVC.swift

var taskObjects:NSMutableArray! = NSMutableArray()

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)    
    self.fetchAllObjects()
}

func fetchAllObjects() {

    var query:PFQuery = PFQuery(className: "Task")

    query.whereKey("username", equalTo: PFUser.currentUser()!)

    query.orderByAscending("dueDate")
    query.addAscendingOrder("desc")

    //fetches values within pointer object
    query.includeKey("deal")

    query.findObjectsInBackgroundWithBlock { (tasks: [AnyObject]!, error:NSError!) -> Void in

        if (error == nil) {

            var temp:NSArray = tasks! as NSArray
            self.taskObjects = temp.mutableCopy() as NSMutableArray

            self.tableView.reloadData()

            println("Fetched objects from server")

        } else {
            println(error?.userInfo)
        }
    }
}


//MARK: - Tasks table view
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.taskObjects.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as TaskCell

    var dateFormatter:NSDateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "M/dd/yy"

    var task:PFObject = self.taskObjects.objectAtIndex(indexPath.row) as PFObject

    cell.desc_Lbl?.text = task["desc"] as? String
    cell.date_Lbl.text = dateFormatter.stringFromDate(task["dueDate"] as NSDate)

    //value of client within Deal pointer object
    if let deal = task["deal"] as? PFObject {
        // deal column has data
        if let client = deal["client"] as? String {
            // client has data
            cell.client_Lbl?.text = client
        }
    }

    //set the tag for the cell's UIButton equal to the indexPath of the cell
    cell.checkbox_Btn.tag = indexPath.row
    cell.checkbox_Btn.addTarget(self, action: "checkCheckbox:", forControlEvents: UIControlEvents.TouchUpInside)
    cell.checkbox_Btn.selected = task["isCompleted"] as Bool

    if (task["isCompleted"] != nil) {
            cell.checkbox_Btn.setBackgroundImage(UIImage(named:(cell.checkbox_Btn.selected ? "CheckedCheckbox" : "UncheckedCheckbox")), forState:UIControlState.Normal)
    }

    cell.selectionStyle = .None

    return cell

}

func checkCheckbox(sender:UIButton!) {
    var senderBtn:UIButton = sender as UIButton
        println("current row: \(senderBtn.tag)")

    //retrieve the PFObject for the row we have selected
    var task:PFObject = self.taskObjects.objectAtIndex(senderBtn.tag) as PFObject
        println("objectID: \(task.objectId)")

    if task["isCompleted"] as NSObject == true {
            task["isCompleted"] = false
        } else {
            task["isCompleted"] = true
        }

    task.saveInBackgroundWithBlock { (success, error) -> Void in

        if (error == nil) {
            println("saved checkbox object in background")
        } else {
            println(error!.userInfo)
        }
    }

    self.tableView.reloadData()
}

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

override func tableView(tableView: UITableView?, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {

    if (editingStyle == UITableViewCellEditingStyle.Delete) {

        var task:PFObject = self.taskObjects.objectAtIndex(indexPath.row) as PFObject

        task.deleteInBackgroundWithBlock({ (success, error) -> Void in

            self.fetchAllObjects()

            self.taskObjects.removeObjectAtIndex(indexPath.row)
        })

    } else if editingStyle == .Insert {

    }
}

【问题讨论】:

    标签: ios swift parse-platform uibutton


    【解决方案1】:

    使用表格和集合视图时,您在自定义单元格中拥有的所有对象都可以在 cellForRowAtIndexPath 中轻松访问(用于 UITables)

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCellWithIdentifier("ActionCell", forIndexPath: indexPath) as ActionCell
    
        var action = actions[indexPath.row] as Action
    
        cell.nameLabel?.text = action.name
        cell.listLabel?.text = action.list
        cell.dateLabel?.text = action.date
        cell.checkboxButton = action.isChecked
        cell.checkBoxButton.setImage(UIImage(named:"checkedImage"), forState:UIControlState.Normal)
        return cell
    }
    

    我建议将常量更改为变量。我也是 Swift 新手,“let”声明了一个静态变量。

    我发现在这些情况下使用条件运算符 (?:) 非常酷:

    cell.checkBoxButton.setImage(UIImage(named:(any_boolean_condition ? "checkedImage" : "uncheckedImage")), forState:UIControlState.Normal)
    

    因此它可以为条件 True 返回一个图像名称,为条件 False 返回另一个名称。

    【讨论】:

    • 谢谢,但我应用了您的代码并在 cell.checkboxButton.setImage 旁边收到此错误... '(UIButton) -> ()' does not have a member named 'setImage'跨度>
    • 我猜你混淆了一些对象。 UIButton 确实有 setImage 方法。如果你的编译器说没有,那么 cell.checkBoxButton 中引用的变量不是 UIButton。另一点是您使用的是 self.isChecked 布尔变量,而您可以使用 UIButton.selected 和 .isSelected 状态:我会为默认状态(未选中的图像)设置一个图像,为后一种状态设置一个选定的图像,然后只是切换 UIButton.selected:
    • 从 Interface Builder 控制单击 UIButton 您必须确保将引用从 IB 拖到代码中。
    • 如果答案有用,请接受:D
    • 非常有用。我仍然计划编辑我的问题,以向未来的 Google 员工展示我的工作代码,但我想我现在没有理由不能接受它。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 2014-08-28
    相关资源
    最近更新 更多