2016-02-03 2 views
0

je les suivantes Protocol:Swift: Protocole de délégation ne pas fixer UILabel correctement

protocol SoundEventDelegate{ 
    func eventStarted(text:String) 
} 

que j'appelle dans cette classe:

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

} 

que j'ai mon ViewController conformes aux normes:

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

Mais quand je cours l'application kleinGrossLabel.text ne change pas. Est-ce que je parle de l'étiquette de la mauvaise façon? Ou est-ce la façon dont je fais la délégation qui est incorrecte?

Voici les liens vers les définitions de Class complètes Sentence et SentenceMarkov

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

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

+0

getters comme ça ne sont pas pratique courante, car votre getter et votre variable ont le même contrôle d'accès, donc n'importe où vous pouvez appeler ce getter, vous pouvez simplement accéder directement à la variable.Ils sont utiles si vous voulez avoir différents niveaux de contrôle d'accès, comme un var privé avec un getter public –

+0

êtes-vous en train de paramétrer le délégué dans votre classe SoundEvent sur un objet réel? –

+0

@WillM. oui voir le premier gist.'let event1 = SoundEvent (texte: "klein", durée: DurationsArray [Int (duréeIndex1)]) 'dans la classe' Sentence' – Thalatta

Répondre

1

Tout d'abord, il n'est pas courant d'avoir un setter dans swift. si vous voulez avoir une propriété en lecture seule, vous pouvez utiliser private(set) var propertyName dans d'autres cas, l'accès simplement la propriété comme mentionné dans le commentaire

Aussi je ne vois pas de raison pour laquelle vous eventArray dans la phrase est de type [SoundEvent?] pas [SoundEvent] comme SoundEvent ne semble pas avoir un failable initialiseur

Comme mentionné avant que vous devez non seulement mettre en œuvre le protocole SoundEventDelegate mais également définir le délégué

le problème est que vous ne pouvez pas vraiment accéder au SoundEventDelegate de la viewcontroller becaus e Vous instancier le SoundEvents intérieur Sentence

var soundEventDelegate: SoundEventDelegate? 

la meilleure façon de le faire serait d'ajouter une soundEventDelegate propriété pour la peine et la mise comme ceci:

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

et à l'intérieur du son, vous devez le régler la délégué pour chaque événement à l'soundEventDelegate de Sentence

vous pouvez le faire comme ceci:

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

ou écrire un autre initialiseur qui prend le délégué

espérons que cette aide

ps: vous ne devriez pas hériter forme NSObject excepts rapides, il est vraiment nécessaire

+0

Question rapide, comment pourrais-je définir mon UILabel dans le contexte ci-dessus? Il est logique d'avoir 'Sentence 'utiliser' SoudEventDelegate', mais comment puis-je utiliser les informations d'un 'eventStart' pour mettre à jour finalement mon' UILabel', quand c'est dans 'ViewController' et non pas' Sentence'? – Thalatta

+1

installez-vous '' 'SoundEvent''' directement dans votre' '' VierviewController'''? Sinon, cela devrait fonctionner de cette façon en définissant les phrases '' '' soundEventDelegate''' il devrait essentiellement déléguer l'appel directement de '' '' SoundEvent''' à '' 'ViewController''' – herby

+0

J'ai créé un terrain de jeu où vous pouvez voir le changement d'étiquette sur le côté droit https://gist.github.com/nafetswirth/e462c17bd9426a7caf8d – herby

2

Vous ne définissez la propriété délégué. C'est nul. Il ne sera jamais appelé.

+0

Comment la propriété delegate est-elle définie? – Thalatta

+0

Quelque part vous avez une instance de votre classe "SoundEvent". Vous devez définir la propriété delegate de cette instance sur l'instance viewController qui implémente les méthodes delegate. – Woodstock

+0

donc 'faible var délégué: ViewControllerDelegate?' – Thalatta