将参数传递给Swift

时间:2015-10-30 19:31:19

标签: ios swift selector uitapgesturerecognizer

我正在构建一个应用程序,用于跟踪大学课程的阅读作业。每个ReadingAssignment都包含一个Bool值,表示读者是否已完成阅读作业。 ReadingAssignments被收集到WeeklyAssignment数组中。我希望用户能够触摸标签并显示复选标记,并将分配显示为已完成。我希望这个触摸也将.checked属性更新为true,这样我就可以保存数据。 所以,我试图让gestureRecognizer调用labelTicked()方法。这适用于打印到控制台。但是,当我尝试传入赋值参数时,它会编译,但在触摸时会因“无法识别的选择器”错误而崩溃。我已经阅读了我在这里可以找到的每个主题,并且没有找到解决方案。他们都说“:”表示带参数的选择器,但仍然没有。 你能看出我做错了吗?

func configureCheckmark(cell: UITableViewCell, withWeeklyAssignment assignment: WeeklyAssignment) {

    let checkLabel = cell.viewWithTag(1002) as! UILabel
    checkLabel.userInteractionEnabled = true
    let gestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("labelTicked:assignment"))
    checkLabel.addGestureRecognizer(gestureRecognizer)

}

@objc func labelTicked(assignment: WeeklyAssignment) {

    assignment.toggleCheckmark()

        if assignment.checked {
            label.text = "✔︎"
        } else {
            label.text = ""
        }
}

我还想传递UILabel checkLabel,以便我可以在labelTicked()方法中更新它。 谢谢你的帮助。

2 个答案:

答案 0 :(得分:22)

这里有两个不同的问题:

  1. 选择器的语法错误; :没有标记参数部分的开头,它只标记该函数接受参数。因此,点击识别器应初始化为UITapGestureRecognizer(target: self, action: "labelTicked:")。轻松修复。这是个好消息。

  2. 坏消息:即使语法完美,它也不会像你在这里设置的那样工作。您的点按识别器无法将WeeklyAssignment对象作为参数传递。实际上,它根本无法传递任何自定义参数。至少,不是那样的。

  3. 然而,它可以传递的是它的sender(通常是手势识别器附加到的视图)。您可以通过将方法更改为

    来获取它
    func labelTicked(sender: AnyObject) {
    

    (请注意,如果您确切知道会发生什么,可以将AnyObject声明为更具体的类型。)

    通过发件人,你现在理论上可以推断出哪个标签被点击,标签对应哪个数据实体,以及该实体的checked属性的状态。我认为这样会变得非常复杂。

    看似简单易懂的事情通常是一个好兆头,我们应该退一步寻找更好的解决方案。

    我建议在这一点上放弃整个GestureRecognizer方法,而是利用表视图中的每个单元格已经开箱即用的“tap recongizing”功能这一事实:{{{ 1}}表视图的委托方法。在那里,您可以轻松使用提供的didSelectRowAtIndexPath:从数据源中检索相应的模型实体,以根据需要读取和修改其参数。通过NSIndexPath,您可以获得对正确单元格的引用并相应地更改其内容。

    Swift 3的更新:

    随着Swift语言的发展和使用基于字符串的选择器(例如cellForRowAtIndexPath:)现在被标记为已弃用,我认为提供答案的小更新是合适的。

    使用更现代的语法,您可以像这样声明您的函数:

    "labelTicked:"

    并使用@objc func labelTicked(withSender sender: AnyObject) {

    初始化您的手势识别器
    #selector

答案 1 :(得分:4)

该功能的正确选择器为labelTicked:。此外,您可以直接使用字符串作为选择器。因此:

let gestureRecognizer = UITapGestureRecognizer(target: self, action: "labelTicked:")

但是当识别器触发时,您无法安排将任意对象传递给方法。更好的方法是创建UITableViewCell的子类。我们称之为AssignmentCell。为子类指定assignment属性,并将labelTicked:方法移至AssignmentCell

如果您在故事板中设计了单元格,则可以在故事板中的标签处添加点击识别器,并将识别器连接到故事板中的单元格labelTicked:方法

在您的表格视图数据源tableView(_:cellForRowAtIndexPath:)中,在您将单元格排队后,将其assignment属性设置为该行的分配。