Swift: Delegation protocol not setting UILabel properly

给你一囗甜甜゛ 提交于 2019-12-12 01:40:12

问题


I have the following Protocol:

protocol SoundEventDelegate{
  func eventStarted(text:String)
}

which I call in this class:

class SoundEvent {
  var text:String
  var duration:Double
  init(text: String, duration: Double){
    self.text = text
    self.duration = duration
}

var delegate : SoundEventDelegate?

func startEvent(){
    delegate?.eventStarted(self.text)

}

  func getDuration() -> Double{
    return self.duration //TODO is this common practice?
  }

} 

Which I have my ViewController conform to:

class ViewController: UIViewController, SoundEventDelegate {
  //MARK:Properties
  @IBOutlet weak var beginButton: UIButton!
  @IBOutlet weak var kleinGrossLabel: UILabel!

  override func viewDidLoad() {
     super.viewDidLoad()
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

  //DELEGATE method
  func eventStarted(text:String){
    kleinGrossLabel.text = text
  }

  //MARK: actions
  @IBAction func startImprovisation(sender: UIButton) {
    var s1:Sentence = Sentence(type: "S3")
    var s2:Sentence = Sentence(type: "S1")
    var newModel = SentenceMarkov(Ult: s1, Penult: s2)
    s1.start()
    beginButton.hidden = true
  } 
}

But when I run the app kleinGrossLabel.text does not change. Am I referring to the label in the wrong way? Or is it the way that I do delegation that is incorrect?

Here are links to the complete Class definitions of Sentence and SentenceMarkov

https://gist.github.com/anonymous/9757d0ff00a4df7a29cb - Sentence

https://gist.github.com/anonymous/91d5d6a59b0c69cba915 - SentenceMarkov


回答1:


First off it's not common practice to have a setter in swift. if you want to have a readonly property you can use private(set) var propertyName in other cases simply access the property like mentioned in the comment

Also i don't see a reason why you eventArray in sentence is of type [SoundEvent?] not [SoundEvent] as SoundEventdoes not seem to have a failable initialiser

Like mentioned before you need to not only implement the SoundEventDelegate protocol but also set the delegate

the problem is that you can't really access the SoundEventDelegate from the viewcontroller because you instantiate the SoundEvents inside Sentence

var soundEventDelegate: SoundEventDelegate?

the easiest way to do this would be adding a soundEventDelegate property for sentence and setting it like this:

let s1:Sentence = Sentence(type: "S3")
let s2:Sentence = Sentence(type: "S1")
s1.soundEventDelegate = self
s2.soundEventDelegate = self

and inside sound you would need the set the delegate for every event to the soundEventDelegate of Sentence

you could do it like this:

var soundEventDelegate: SoundEventDelegate? = nil {
    didSet {
        eventArray.forEach({$0.delegate = soundEventDelegate})
    }
}

or write another initialiser that takes the delegate

hope this helps

p.s: you shouldn't inherit form NSObject in swift excepts it's really necessary




回答2:


You never set the delegate property. It's nil. It will never be called.



来源:https://stackoverflow.com/questions/35188922/swift-delegation-protocol-not-setting-uilabel-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!