简体   繁体   English

对UIButton的操作不起作用

[英]Action on a UIButton doesn't work

I'm trying to understand the MVVM pattern by learning from a tutorial ( link ) and I can't get an action I've added to a UIButton to work (I'm using Swift 3.0). 我试图通过从教程( 链接 )中学习来了解MVVM模式,但是我无法执行已添加到UIButton的操作 (我使用的是Swift 3.0)。 I've tried debugging for hours, studied this thread ( @selector in swift ) and others, and I'm still stuck. 我已经尝试调试了几个小时,研究了这个线程( swift中的@selector )和其他线程,但仍然遇到问题。 When I click the button, nothing happens at all. 当我单击按钮时,什么也没有发生。 I tried various syntax options with the selector and I think what you see below is correct. 我用选择器尝试了各种语法选项,我认为您在下面看到的是正确的。 I think the protocol I'm using might be contributing to the problem but, given my limited experience with protocols, I could be completely wrong about that. 我认为我正在使用的协议可能是导致此问题的原因,但是由于我对协议的经验有限,因此我可能完全错了。

I'll put all the code here in case anybody wants to drop it into Xcode. 我将所有代码放在这里,以防有人想要将其放入Xcode。 The action in question here is in my UIViewController that I add to showGreetingButton : 这里有问题的动作是在我添加到showGreetingButton UIViewController中:

class GreetingViewController : UIViewController {
  let showGreetingButton = UIButton()
  @IBOutlet weak var greetingLabel: UILabel!

  var viewModel: GreetingViewModelProtocol! {
    didSet {
      self.viewModel.greetingDidChange = { [unowned self] viewModel in
        self.greetingLabel.text = viewModel.greeting
      }
    }
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    showGreetingButton.backgroundColor = UIColor.red
    showGreetingButton.tintColor = UIColor.black
    showGreetingButton.setTitle("Show Greeting", for: .normal)

    // I add the action here:
    showGreetingButton.addTarget(self.viewModel, action: #selector(GreetingViewModel.showGreeting), for: .touchUpInside)

    showGreetingButton.translatesAutoresizingMaskIntoConstraints = false    
    view.addSubview(showGreetingButton)
    let buttonTop = NSLayoutConstraint(item: showGreetingButton, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.greaterThanOrEqual, toItem: view, attribute: NSLayoutAttribute.topMargin, multiplier: 1.0, constant: 20)
    let buttonLeading = NSLayoutConstraint(item: showGreetingButton, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.leadingMargin, multiplier: 1.0, constant: 0.0)
    showGreetingButton.contentEdgeInsets = UIEdgeInsetsMake(2, 2, 2, 2)
    NSLayoutConstraint.activate([buttonTop, buttonLeading])

    let model = Person(firstName: "David", lastName: "Blaine")

    let viewModel = GreetingViewModel(person: model)

    self.viewModel = viewModel
  }
}

My view model is called GreetingViewModel which adopts a protocol: 我的视图模型称为GreetingViewModel,它采用了一种协议:

protocol GreetingViewModelProtocol: class {      
  var greeting: String? { get }
  var greetingDidChange: ((GreetingViewModelProtocol) -> ())? { get set }
  init(person: Person)
  func showGreeting()
}

class GreetingViewModel : GreetingViewModelProtocol {
  let person: Person
  var greeting: String? {
    didSet {
      self.greetingDidChange?(self)
    }
  }

  var greetingDidChange: ((GreetingViewModelProtocol) -> ())?

  required init(person: Person) {
    self.person = person
  }

  @objc func showGreeting() {
    self.greeting = "Hello" + " " + self.person.firstName + " " + self.person.lastName
  }
}

And my simple model is: 我的简单模型是:

struct Person {
  let firstName: String
  let lastName: String
}

Any help would be really, really appreciated. 任何帮助将是非常,非常感谢。

Move these lines to before you set your button's target: 在设置按钮目标之前,将这些行移动到:

let viewModel = GreetingViewModel(person: model)
self.viewModel = viewModel

Right now you are adding self.viewModel as the target, but self.viewModel is nil 现在,您要添加self.viewModel作为目标,但是self.viewModelnil

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM