【问题标题】:Swift: Delegation protocol not setting UILabel properlySwift:委托协议未正确设置 UILabel
【发布时间】:2016-05-13 08:25:10
【问题描述】:

我有以下Protocol

protocol SoundEventDelegate{
  func eventStarted(text:String)
}

我在这堂课中称之为:

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

} 

我的ViewController 符合:

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

但是当我运行应用程序时,kleinGrossLabel.text 并没有改变。我是否以错误的方式引用标签?还是我做委托的方式不正确?

这里是SentenceSentenceMarkov 的完整Class 定义的链接

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

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

【问题讨论】:

  • 像这样的 getter 并不常见,因为您的 getter 和您的变量具有相同的访问控制,因此在任何可以调用该 getter 的地方,您都可以直接访问该变量。如果您想拥有不同级别的访问控制,例如带有公共 getter 的私有 var,它们会很有用
  • 您是否曾经将 SoundEvent 类中的委托设置为实际对象?
  • @WillM。是的,请参阅Sentence 类中的第一个要点。let event1 = SoundEvent(text: "klein", duration: DurationsArray[Int(durationIndex1)])
  • 设置委托属性的哪一部分? IE。 soundEvent.delegate = self
  • 他没有。他所做的只是创建一个SoundEvent 的实例。

标签: ios swift protocols delegation


【解决方案1】:

您从不设置委托属性。是零。它永远不会被调用。

【讨论】:

  • 委托属性是如何设置的?
  • 某处你有一个“SoundEvent”类的实例。您需要将该实例的委托属性设置为实现委托方法的 viewController 实例。
  • 所以weak var delegate:ViewControllerDelegate?
  • 如何从类中引用ViewController的实例?
  • soundEvent.delegate = self ------ 在您的 vc 实现中,其中 soundEvent 是您的 SoundEvent 实例。
【解决方案2】:

首先,在 swift 中有一个二传手并不常见。如果你想拥有一个只读属性,你可以使用private(set) var propertyName 在其他情况下,只需访问评论中提到的属性

我也看不出为什么你在句子中的eventArray[SoundEvent?] 类型而不是[SoundEvent] 因为SoundEvent似乎没有失败的初始化程序

如前所述,您不仅需要实现 SoundEventDelegate 协议,还需要设置委托

问题是您无法真正从视图控制器访问SoundEventDelegate,因为您在Sentence 中实例化了SoundEvents

var soundEventDelegate: SoundEventDelegate?

最简单的方法是为句子添加soundEventDelegate 属性并将其设置如下:

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

在声音内部,您需要将每个事件的委托设置为 soundEventDelegateSentence

你可以这样做:

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

或编写另一个接受委托的初始化程序

希望对你有帮助

p.s: 你不应该在 swift 中继承表单 NSObject 除非它真的有必要

【讨论】:

  • 快速提问,我将如何在上述上下文中设置我的 UILabel?让Sentence 使用SoudEventDelegate 是有意义的,但是我如何使用eventStart 的信息来最终更新我的UILabel,当它在ViewController 而不是Sentence 时?
  • 您是否直接在您的VierviewController 内部实例化SoundEvent?如果不是,它应该通过设置句子soundEventDelegate 以这种方式工作,它基本上应该将调用直接从SoundEvent 委托给ViewController
  • 我创建了一个游乐场,您可以在其中看到右侧标签的变化gist.github.com/nafetswirth/e462c17bd9426a7caf8d
猜你喜欢
  • 2018-01-13
  • 2011-05-13
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多