我正在构建一个应用程序,用于跟踪大学课程的阅读作业。每个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()方法中更新它。 谢谢你的帮助。
答案 0 :(得分:22)
这里有两个不同的问题:
选择器的语法错误; :
没有标记参数部分的开头,它只标记该函数接受参数。因此,点击识别器应初始化为UITapGestureRecognizer(target: self, action: "labelTicked:")
。轻松修复。这是个好消息。
坏消息:即使语法完美,它也不会像你在这里设置的那样工作。您的点按识别器无法将WeeklyAssignment
对象作为参数传递。实际上,它根本无法传递任何自定义参数。至少,不是那样的。
然而,它可以传递的是它的sender
(通常是手势识别器附加到的视图)。您可以通过将方法更改为
func labelTicked(sender: AnyObject) {
(请注意,如果您确切知道会发生什么,可以将AnyObject
声明为更具体的类型。)
通过发件人,你现在理论上可以推断出哪个标签被点击,标签对应哪个数据实体,以及该实体的checked
属性的状态。我认为这样会变得非常复杂。
看似简单易懂的事情通常是一个好兆头,我们应该退一步寻找更好的解决方案。
我建议在这一点上放弃整个GestureRecognizer
方法,而是利用表视图中的每个单元格已经开箱即用的“tap recongizing”功能这一事实:{{{ 1}}表视图的委托方法。在那里,您可以轻松使用提供的didSelectRowAtIndexPath:
从数据源中检索相应的模型实体,以根据需要读取和修改其参数。通过NSIndexPath
,您可以获得对正确单元格的引用并相应地更改其内容。
随着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
属性设置为该行的分配。