"#selector" относится к методу, который не подвергается Objective-C
Новый Xcode 7.3, передающий параметр через addTarget, обычно работает для меня, но в этом случае он выдает ошибку в заголовке. Есть идеи? Он выбрасывает другой, когда я пытаюсь изменить его на @objc
Спасибо!
cell.commentButton.addTarget(self, action: #selector(FeedViewController.didTapCommentButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
Селектор это звонит
func didTapCommentButton(post: Post) {
}
3 ответа
В моем случае функция селектора была private
, Однажды я удалил private
ошибка исчезла. То же самое касается fileprivate
,
В Swift 4
Вам нужно будет добавить @objc
к объявлению функции. До Swift 4 это было сделано неявно.
Вам нужно использовать @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
}
Попробуйте использовать селектор, указывающий на функцию-оболочку, которая в свою очередь вызывает функцию-делегат. Это сработало для меня.
cell.commentButton.addTarget(self, action: #selector(wrapperForDidTapCommentButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
-
func wrapperForDidTapCommentButton(post: Post) {
FeedViewController.didTapCommentButton(post)
}
Как вы знаете selector
[О] говорит, чтоObjective-C
следует использовать время выполнения. Объявления, отмеченные какprivate
или fileprivate
по умолчанию не доступны для среды выполнения Objective-C. Поэтому у вас есть два варианта:
- Отметьте свой
private
илиfileprivate
заявление@objc
[Около] - Использовать
internal
,public
,open
модификатор доступа [О программе]