Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does UIButton addTarget self work?

I try figure out why self point to the GameViewController instead of Answer

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)
    }
}
like image 829
Atsuo Sakakihara Avatar asked Feb 25 '16 19:02

Atsuo Sakakihara


People also ask

How do I add a target to UIButton?

Using a UIControl with a closure callback viewDidLoad() let button = UIButton(type: . system) button. addTarget(self, action: #selector(buttonTapped(_:)), for: . touchUpInside) } @IBAction func buttonTapped(_ sender: UIButton) { print("Button tapped!") } }

What is UIButton Swift?

A control that executes your custom code in response to user interactions.

How do I add a target to a button in Swift 4?

If its the own profile of the current user, the button should add the target "go to settings". If its a different user, I want to add a follow/unfollow action. After checking all parameters, my code should work.

How do I create a button action in Swift?

SwiftUI's button is similar to UIButton , except it's more flexible in terms of what content it shows and it uses a closure for its action rather than the old target/action system. To create a button with a string title you would start with code like this: Button("Button title") { print("Button tapped!") }


1 Answers

addTarget:action:forControlEvents: tells the control (answerButton in this case) what method to call, and what object to call it on, when the user taps the button. Looking at your code in more detail:

 answerButton.addTarget(self, action: "didPressAnswerButton:", forControlEvents: .TouchUpInside)
  • When the user taps a button, the TouchUpInside event fires on the answerButton, and when that happens we want to invoke a method didPressAnswerButton: on an Answer object
  • So, we need to tell answerButton what do do when this TouchUpEvent fires. You do this calling the addTarget:action:forControlEvents method on the answerButton
  • The self argument tells the answerButton what object to notify about the event: it is the target. In this context, self is an Answer object.
  • The "didPressAnswerButton:" argument indicates what method the answerButton should call in response to the tap event: this is the action

This is the target-action mechanism of Objective-C/Cocoa. It's a very common pattern, it's worth it to read the linked documentation to learn a bit more about how it works. The key is that this is based on Objective-C* message passing: in the code above, "didPressAnswerButton:" indicates a selector, which when paired with a target (self), tells the answerButton how to send a "message" to the target when the user taps the button.

Also, note that when you are editing a storyboard and ctrl-drag from a button to your view controller and select a method, you are also setting up a target/action using this same mechanism. You select the target object by dragging to the view controller icon (or some other icon), and then you pick the action/selector when clicking on a method name in the popup.

* Target-Action was originally designed for Objective-C, but for the common case of implementing a view controller, you can assume Swift works the same way. Just note when reading documentation that Swift uses simple strings for actions, whereas Objective-C uses @selector(...).

like image 154
Mike Mertsock Avatar answered Sep 19 '22 17:09

Mike Mertsock