2014-10-03 9 views
26

Impossibile connettersi alla proprietà delegata di CustomView dichiarata come @IBOutlet su ViewController in Interface Builder: semplicemente non è possibile stabilire una connessione.Interface Builder, @IBOutlet e protocolli per delegate e dataSource in Swift

Ecco il codice

class CustomView: UIView { 
    @IBOutlet var delegate: CustomViewDelegate? 
} 

@objc protocol CustomViewDelegate { 
    ... 
} 


class ViewController: UIViewController, CustomViewDelegate { 
    ... 
} 

@objc viene utilizzato a causa di swift protocol, IBOutlet property cannot have non-object type, non so perché protocol CustomViewDelegate: class {} non funziona.

Chiunque altro sono imbattuto in una cosa del genere?

+0

La vostra 'UIViewController' in Interface Builder ha sua categoria specificatamente impostato a' ViewController'? Inoltre, di solito è un requisito (l'ultima volta che ho controllato) che le proprietà di '@ IBOutlet' siano definite come tipi implicitamente scartati, come ad esempio:' CustomViewDelegate! '. Ciò consente loro di essere "nulli" durante l'istanziazione, pur consentendo di usarli senza il binding opzionale dopo che sono stati cablati. –

risposta

56

Dalle note di rilascio Xcode:

Interface Builder non supporta il collegamento a una presa in un file di Swift quando il tipo di uscita è un protocollo.

Soluzione alternativa: dichiarare il tipo di presa come AnyObject o NSObject, collegare gli oggetti alla presa utilizzando Interface Builder, quindi modificare il tipo di presa sul protocollo.

EDIT: Xcode note 9 beta 3 di rilascio dicono che questa soluzione non dovrebbe essere più necessario.

+3

Wowzer! Questo ha funzionato, grazie. Apple ... per favore, prendilo insieme! – josephap

+0

No. "La classe non è conforme ai valori-chiave" dopo la modifica al tipo di protocollo. – stone

+0

Questo ha funzionato solo parzialmente per me. In un caso, in cui ho definito il mio delegato su un UIView per essere collegato a un UIViewController, ha funzionato. In un altro, dove definisco il mio delegato su un UIViewController per essere collegato a un altro UIViewController, non lo è. Ho provato così tante configurazioni. Qualche idea @matt che cosa potrebbe succedere qui? – josephap

8

Un altro che non è abbastanza, ma:

@IBOutlet weak var ibDelegate: NSObject? 
@IBOutlet weak var ibDataSource: NSObject? 
var delegate: MultipleButtonViewDelegate? { return ibDelegate as? MultipleButtonViewDelegate } 
var dataSource: MultipleButtonViewDataSource? { return ibDataSource as? MultipleButtonViewDataSource } 
+0

Buona risposta! Utilizzare in questo modo per prevenire il tipo di cambiamento in genere il punto vendita. – t4nhpt

13

Adam Waite provides a nice workaround. Io però preferisco la seguente soluzione come sottolinea la soluzione e la proprietà supplementare può anche essere facilmente rimosso una volta Xcode si fissa.

class CustomView: UIView { 
    @IBOutlet 
    public var delegate: CustomViewDelegate? 

    /// Workaround for Xcode bug that prevents you from connecting the delegate in the storyboard. 
    /// Remove this extra property once Xcode gets fixed. 
    @IBOutlet 
    public var ibDelegate: AnyObject? { 
     get { return delegate } 
     set { delegate = newValue as? CustomViewDelegate } 
    } 

    func someMethod() { 
     // Here we always refer to `delegate`, not `ibDelegate` 
     delegate?.onSomethingHappened() 
    } 
} 

@objc protocol CustomViewDelegate { 
    ... 
} 

Ehi, è questo bug già un anno e mezzo di anni fa?

1

Per me, la ragione era la vista tavolo era nil al punto ho cercato di impostare è DataSource e delegato. Ciò era dovuto al inizializzatore designato chiamando initWithNibName:bundle: che non garantisce initialized connections. Differire mio delegato e l'impostazione di origine dati per viewDidload funzionato come un fascino.

2

Questo è un vecchio thread, ma ho pensato di notare che a partire dal 9 Xcode beta 3, è ora possibile collegare un delegato personalizzato scritto in rapido al Interface Builder.

Secondo le note di rilascio

Interface Builder ora riconosce punti vendita, azioni e ispezionabili proprietà dichiarate sulle classi che hanno un protocollo di estensione Swift. (22201035)

// Can connect this to interface builder now  
class MyViewController: UIViewController { 
    @IBOutlet weak var myDelegate: TheNewDelegate? 
} 
Problemi correlati