ios - UIButton 上的操作不起作用

标签 ios swift uibutton

我试图通过学习教程( link )来理解 MVVM 模式,并且我无法让我添加到 UIButton 的操作发挥作用(我使用 Swift 3.0)。我已经尝试调试几个小时,研究了这个线程( @selector in swift )和其他线程,但我仍然陷入困境。当我单击按钮时,什么也没有发生。我使用选择器尝试了各种语法选项,我认为您在下面看到的内容是正确的。我认为我正在使用的协议(protocol)可能会导致该问题,但鉴于我在协议(protocol)方面的经验有限,我的看法可能完全错误。

我将把所有代码放在这里,以防有人想将其放入 Xcode 中。这里有问题的操作位于我添加到 showGreetingButtonUIViewController 中:

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
  }
}

我的 View 模型称为 GreetingViewModel,它采用以下协议(protocol):

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
  }
}

我的简单模型是:

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

任何帮助都将非常非常感谢。

最佳答案

将这些行移至设置按钮目标之前:

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

现在您正在添加 self.viewModel 作为目标,但 self.viewModelnil

关于ios - UIButton 上的操作不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40314907/

相关文章:

objective-c - 从迭代NSMutableArray中删除对象

ios - 如何更改 JQM 中 slider 的文本标签?

ios - 在 UITableView 页脚 View 中定位自定义 UILabel

ios - 详细信息披露按钮和披露指示器有什么区别?

ios - 在UIButton上添加“点击”效果

iphone - textFieldDidEndEditing 替代方案

ios - 使用 SFSpeechRecognizer 的正确方法?

ios - 具有多任务处理功能的 CMMotionManager

ios - 检查用户是否打开了每个 View Controller

ios - 转换为 swift 3.0 时,UIButton 上 'dismiss()' 的使用不明确