5

我试着弄清楚为什么self指向 GameViewController 而不是 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)
    }
}

答案.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)
    }
}
4

1 回答 1

15

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 应该调用什么方法来响应点击事件:这是动作

这是 Objective-C/Cocoa 的目标-动作机制。这是一种非常常见的模式,值得阅读链接的文档以了解更多关于它的工作原理。关键是这是基于 Objective-C* 消息传递:在上面的代码中,"didPressAnswerButton:"表示选择器,当与目标 ( ) 配对时self,告诉 answerButton 如何在用户点击时向目标发送“消息”按钮。

另外,请注意,当您编辑情节提要并从按钮按住 ctrl 拖动到视图控制器并选择方法时,您还使用相同的机制设置目标/动作。您通过拖动到视图控制器图标(或其他图标)来选择目标对象,然后在单击弹出窗口中的方法名称时选择操作/选择器。

* Target-Action 最初是为 Objective-C 设计的,但是对于实现视图控制器的常见情况,您可以假设 Swift 以相同的方式工作。请注意,在阅读文档时,Swift 使用简单的字符串来执行操作,而 Objective-C 使用@selector(...).

于 2016-02-25T20:13:12.233 回答