Как написать селектор, который принимает аргумент в Swift 3

В Swift 2 это работало (я умышленно не рассматривал методы просмотра таблицы) …

import Foundation import UIKit private extension Selector { static let didTapButton = #selector(TableVC.buttonTapped(_ :)) } class TableVC: UITableViewController{ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let btnAccView:UIButton = UIButton(frame: CGRectMake(0, 0, 27, 27)) btnAccView.addTarget(self, action: .didTapButton, forControlEvents: UIControlEvents.TouchUpInside) btnAccView.tag = indexPath.row } func buttonTapped(sender: UIButton){ print("button tapped at row \(sender.tag)") } } 

В Swift 3 это вызывает ошибку: «TableVC не имеет кнопки-члена».

Мне просто нужно написать селектор, который принимает аргумент. Я пытался возиться с синтаксисом во всех отношениях, о которых я могу думать, но ничего не сработало. Спасибо за вашу помощь

Прежде всего, вам нужно изменить buttonTapped чтобы первая метка аргумента была подавлена. Вставьте знак подчеркивания перед меткой внутреннего аргумента, чтобы он выглядел следующим образом:

 func buttonTapped(_ sender: UIButton) { 

Раньше его сигнатурой метода был TableVC.buttonTapped(sender:) , и теперь его подпись будет TableVC.buttonTapped(_:) . Возможно, вам придется удалить пробел между подчеркиванием и двоеточием в вашем расширении, но после этого он должен работать.

Как примечание, есть ли какая-то конкретная причина, по которой вы используете расширение на Selector ? Эта модель расширения наиболее полезна обычно с такими вещами, как имена уведомлений, которые могут быть легко опечатаны, что приводит к сложным ошибкам. Поскольку компилятор Swift автоматически проверяет объявления #selector независимо от того, где они размещены, вы можете просто поместить его прямо в свой код – не требуется расширение.

Вы можете сэкономить себе скорбь, позволив компилятору вывести часть сигнатуры функции. В твоем случае…

 class TableVC: UIViewController { func buttonTapped(sender: UIButton) { /*...*/ } } 

Вы можете ссылаться на него извне класса TableVC как:

  • #selector(TableVC.buttonTapped(sender:))
  • #selector(TableVC.buttonTapped)

Второй работает, потому что в buttonTapped есть только одна функция TableVC , поэтому компилятору не нужна полная подпись, чтобы устранить ее.

Из кода внутри TableVC вы можете упростить его шаг дальше и просто использовать #selector(buttonTapped) , потому что в этот момент вы находитесь в области класса и можете безопасно вывести метод класса.

( #selector(TableVC.buttonTapped(_:)) которую вы используете, работает только в том случае, если ваш метод объявлен как func buttonTapped(_ sender: UIButton) . В вашем случае использования не имеет значения, имеет ли параметр sender метка аргумента или нет – вы просто должны быть последовательны в этом между вашим объявлением func и вашим выражением #selector .)

И, как отмечает @Bob, нет необходимости в расширении Selector , потому что компилятор уже проверяет селектор.

Используйте следующий способ реализации селектора для действия кнопки:

 import UIKit class MyViewController: UIViewController { let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50)) override init?(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) let action = #selector(MyViewController.tappedButton) myButton.addTarget(self, action: action, forControlEvents: .touchUpInside) } func tappedButton(sender: UIButton?) { print("tapped button") } required init?(coder: NSCoder) { super.init(coder: coder) } } 
  • Как получить имя и имя от входа в Google?
  • iOS Swift: как проверить наличие Bluetooth-устройства в iPhone
  • Как я могу изменить шрифт панели навигации UIImagePickerController?
  • scrollViewDidEndZooming не вызывается при масштабировании в UIScrollView
  • Сделать запрос с указателем в парсе и быстром
  • Получить правильное положение subView с автоматической компоновкой
  • Как создать анимацию перетаскивания для UIView?
  • Firebase Storage скачать для локального файла
  • NSBatchUpdateRequest вызывает ошибку в Swift
  • Вызов родительского метода из дочернего?
  • Элементы панели навигации не отображаются на реальном устройстве
  • Interesting Posts

    UISegmentedControl не уважает NSConstraint для ширины

    Как создать класс, который использует MPMoviePlayerController для воспроизведения видео с веб-сервера без каких-либо проблем с памятью

    Преобразовать строку даты (2016-04-27T08: 06: 07.531Z) в определенный формат даты dd.MM.YYYY

    Место обновления iOS 10, когда приложение завершено

    EventKitUI / EKCalendarChooser нужен доступ к контактам – почему?

    Как перенести приложение на передний план программно

    Разработка iOS: Каковы некоторые причины, по которым я должен использовать XAuth для аутентификации пользователя Twitter?

    iphone: управление памятью с dispatch_async

    Storyboard & Segue – Передача данных, я делаю это хорошо?

    Как включить автоматический поворот определенного контроллера просмотра, если приложение не разрешено вращаться в iOS?

    Запустить несколько экземпляров NSOperation с NSURLConnection?

    ios setHidden: НЕТ при начале длинного метода не отображается на дисплее

    Ничего не отображается в элементах контроллера панели таблеток, когда добавлена ​​ссылка для раскадровки

    Как использовать плагин-плагин-плагин для платформы iOS?

    Рекомендации iOS – проверьте некоторые условия перед запуском методов

    Давайте будем гением компьютера.