2013-02-08 20 views
8

Ho due finestre: la finestra A è caricata da NIB; e la finestra B è creata a livello di codice.binding: toObject: withKeyPath: options: è un collegamento unidirezionale?

Entrambe le finestre hanno un NStextView: l'attributedString del TextView in Window A è legato alla proprietà text di un modello utilizzando IB; mentre la stringa attribuita della vista testo in Finestra B è associata alla proprietà text del modello utilizzando il metodo -[NSObject bind:toObject:withKeyPath:options:].

[textview bind:@"attributedString" toObject:obj withKeyPath:@"text" options:nil]; 

Ecco la cosa strana: il TextView in finestra B è infatti legato al obj.text, ma i cambiamenti nella TextView non viene mai aggiornato per obj.text. Ma, se ho apportato modifiche nella finestra di testo della Finestra A, lo obj.text e la vista testo nella Finestra B vengono aggiornati di conseguenza.

Quindi, sto pensando, il metodo -[NSObject bind:toObject:withKeyPath:options:] è solo per il collegamento unidirezionale. Non ho trovato una spiegazione chiara nelle documentazioni di Cocoa. Qualcuno ha esperienza con questo problema? Come implementate l'associazione bidirezionale nel codice?

risposta

3

Le associazioni di cacao sono intrinsecamente bidirezionali, ma determinati comportamenti (come l'aggiornamento continuo/live dei campi di testo) richiedono opzioni specifiche da impostare. In IB dovrai assicurarti che la casella di controllo "Aggiorna continuamente valore" sia selezionata. Per ottenere un comportamento equivalente a livello di codice, è necessario specificare options sull'associazione. Questo potrebbe essere simile a questa:

[textview bind: NSAttributedStringBinding 
     toObject: obj 
    withKeyPath: @"text" 
     options: (@{ 
       NSContinuouslyUpdatesValueBindingOption : @YES })]; 

Vale la pena ricordare che, quando la creazione di un legame a livello di codice, vale la pena controllare un equivalente vincolante in IB e fare in modo che stai passando tutte le stesse impostazioni per l'associazione programmatica. Ad esempio, vedo in IB che le opzioni "Consenti modifica selezione valori multipli", "Imposta condizionatamente modificabili" e "Solleva per chiavi non applicabili" sono tutte selezionate per impostazione predefinita per il binding di stringa attribuita di NSTextView. Ciò significherebbe la nostra programmatica vincolante dovrebbe probabilmente davvero assomigliare:

[textview bind: NSAttributedStringBinding 
     toObject: obj 
    withKeyPath: @"text" 
     options: (@{ 
       NSContinuouslyUpdatesValueBindingOption : @YES, 
       NSAllowsEditingMultipleValuesSelectionBindingOption : @YES, 
       NSConditionallySetsEditableBindingOption : @YES, 
       NSRaisesForNotApplicableKeysBindingOption : @YES })]; 
+0

Questo non funzionava ancora per me. Ho trovato la risposta (per il mio caso) qui -> http://stackoverflow.com/questions/1169097/can-you-manually-implement-cocoa-bindings –

+0

Non sono sicuro della pertinenza della domanda collegata sopra . L'associazione qui menzionata si trova tra due oggetti NSControl: non è richiesta alcuna implementazione di associazione personalizzata. – stevesliva

2

Sì, legano: ToObject: withKeyPath: opzioni: è un modo e nessuna opzione può influenzare questo. Questo non è lo stesso di come si crea l'associazione nel file .nib. Come al solito, Apple ha dimenticato di menzionare una cosa tanto semplice nei suoi documenti. La soluzione più semplice qui è quella di creare il binding inverso allo stesso tempo quando ne crei uno avanti. Questo NON annulla il codice quando si assegna il valore. Ecco l'esempio con i valori predefiniti dell'utente:

// two way binding of MyObject.myValue to user defaults 
[NSUserDefaultsController.sharedUserDefaultsController.values bind: @"myValueInDefaults" 
                  toObject: myObject 
                 withKeyPath: @"myValue" 
                  options: @{@"NSContinuouslyUpdatesValue":@YES}]; 

[myObject bind: @"myValue" 
     toObject: NSUserDefaultsController.sharedUserDefaultsController 
    withKeyPath: @"values.myValueInDefaults" 
     options: @{@"NSContinuouslyUpdatesValue":@YES}]; 
+0

Devo utilizzare due NSValueTransformers, se devo convertire un valore in un altro e viceversa, per la chiave NSValueTransformerBindingOption, o uno è sufficiente? – rraallvv

+0

Poiché questi collegamenti non sono collegati tra loro, penso che siano necessari due NSValueTransformers, uno per ciascun binding. Ma non ho usato NSValueTransformerBindingOption e non posso dirlo con certezza. –

+0

Vedo, per esempio da gradi a radianti e viceversa, penso che ci sarebbero necessari due di loro, grazie – rraallvv