Новый Xcode 7.3, передающий параметр с помощью addTarget, обычно работает для меня, но в этом случае он бросает ошибку в заголовок. Есть идеи? Он бросает другой, когда я пытаюсь изменить его на @objc
Спасибо!
cell.commentButton.addTarget(self, action: #selector(FeedViewController.didTapCommentButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
Селектор, вызывающий
func didTapCommentButton(post: Post) {
}
Ответ 1
В моем случае функция селектора была private
. Как только я удалил private
ошибка исчезла. То же самое касается fileprivate
.
В Swift 4
Вам нужно будет добавить @objc
в объявление функции. До быстрого 4 это было неявно выведено.
Ответ 2
Вам нужно использовать атрибут @objc
на didTapCommentButton(_:)
чтобы использовать его с #selector
.
Вы говорите, что сделали это, но получили еще одну ошибку. Я предполагаю, что новая ошибка заключается в том, что Post
не является типом, совместимым с Objective-C. Вы можете только выставить метод Objective-C, если все его типы аргументов и его тип возврата совместимы с Objective-C.
Вы могли бы исправить это, сделав Post
подклассом NSObject
, но это не будет иметь значения, потому что аргумент didTapCommentButton(_:)
не будет Post
любом случае. Аргумент функции действия является отправителем действия, и отправителем будет commentButton
, который предположительно является UIButton
. Вы должны объявить didTapCommentButton
следующим образом:
@objc func didTapCommentButton(sender: UIButton) {
// ...
}
После этого вы столкнетесь с проблемой получения Post
соответствующего нажатой кнопке. Существует несколько способов получить его. Вот один.
Я собираюсь (поскольку ваш код говорит cell.commentButton
), что вы настраиваете представление таблицы (или представление коллекции). И поскольку ваша ячейка имеет нестандартное свойство с именем commentButton
, я предполагаю, что это пользовательский подкласс UITableViewCell
. Поэтому позвольте предположить, что ваша ячейка PostCell
объявлена следующим образом:
class PostCell: UITableViewCell {
@IBOutlet var commentButton: UIButton?
var post: Post?
// other stuff...
}
Затем вы можете подойти к иерархии представлений с помощью кнопки, чтобы найти PostCell
, и получить сообщение от него:
@objc func didTapCommentButton(sender: UIButton) {
var ancestor = sender.superview
while ancestor != nil && !(ancestor! is PostCell) {
ancestor = view.superview
}
guard let cell = ancestor as? PostCell,
post = cell.post
else { return }
// Do something with post here
}
Ответ 3
Попробуйте указать селектор на функцию-обертку, которая, в свою очередь, вызывает функцию делегата. Это сработало для меня.
cell.commentButton.addTarget(self, action: #selector(wrapperForDidTapCommentButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
-
func wrapperForDidTapCommentButton(post: Post) {
FeedViewController.didTapCommentButton(post)
}