Как UIButton addTarget самостоятельно работает?

Я пытаюсь выяснить почему self указать на GameViewController вместо ответа

GameViewController.swift

class GameViewController: UIViewController {
    var gameplay = QuestionsController(colors: colors)

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(gameplay.answersController.answers[0].button)
    }

    func didPressAnswerButton(sender: UIButton!) {
        sender.setTitle("Im from GameViewController class", forState: .Normal)
    }
}

QuestionsController.swift

class QuestionsController {
    var question: Question
    var answersController: AnswersController
}

AnswersController.swift

class AnswersController {
    var answers = [Answer]()

    func prepareAnswers() {
        let answer = Answer()
        answers.append(answer)
    }
}

Answer.swift

class Answer{
    let button: UIButton

    func prepareButton() {
        let answerButton = AnswerButton(type: .System)
        answerButton.addTarget(self, action: "didPressAnswerButton:", forControlEvents: .TouchUpInside)
        button = answerButton
    }

    func didPressAnswerButton(sender: UIButton!) {
        sender.setTitle("Im from Answer class", forState: .Normal)
    }
}

1 ответ

Решение

addTarget:action:forControlEvents: говорит контроль (answerButton в данном случае) какой метод вызывать и какой объект вызывать, когда пользователь нажимает кнопку. Рассмотрим ваш код более подробно:

 answerButton.addTarget(self, action: "didPressAnswerButton:", forControlEvents: .TouchUpInside)
  • Когда пользователь нажимает кнопку, TouchUpInside событие происходит на answerButton и когда это произойдет, мы хотим вызвать метод didPressAnswerButton: на Answer объект
  • Итак, нам нужно сказать answerButton что делать, когда срабатывает TouchUpEvent. Вы делаете это, призывая addTarget:action:forControlEvents метод на answerButton
  • self аргумент говорит answerButton какой объект уведомить о событии: это цель. В данном контексте, self является Answer объект.
  • "didPressAnswerButton:" Аргумент указывает, какой метод должен вызывать answerButton в ответ на событие tap: это действие

Это механизм целевого действия Objective-C/ Какао. Это очень распространенный шаблон, стоит прочитать связанную документацию, чтобы узнать немного больше о том, как он работает. Ключ в том, что это основано на передаче сообщений Objective-C*: в приведенном выше коде "didPressAnswerButton:" указывает селектор, который при сопряжении с целью (self), сообщает answerButton, как отправить "сообщение" цели, когда пользователь нажимает кнопку.

Также обратите внимание, что когда вы редактируете раскадровку и перетаскиваете Ctrl от кнопки до вашего контроллера представления и выбираете метод, вы также настраиваете цель / действие, используя тот же механизм. Вы выбираете целевой объект, перетаскивая его на значок контроллера представления (или другой значок), а затем выбираете действие / селектор, щелкая имя метода во всплывающем окне.

* Target-Action изначально был разработан для Objective-C, но для общего случая реализации контроллера представления можно предположить, что Swift работает аналогичным образом. Просто отметьте при чтении документации, что Swift использует простые строки для действий, тогда как Objective-C использует @selector(...),

Другие вопросы по тегам