@IBInspectable con enum?

Vorrei creare @IBInspectable elemento come si vede in foto qui sotto :

@IBInspectable con enum?

la mia idea è di usare qualcosa come enum tipo per @IBInspectable, ma sembra che non è il caso, come tutte le idee per implementare elemento come questo ?

EDIT:

Sembra @IBInspectable supporta solo i seguenti tipi :

  • Int
  • CGFloat
  • Double
  • String
  • Bool
  • CGPoint
  • CGSize
  • CGRect
  • UIColor
  • UIImage

bummer

  • Una soluzione di questo genere, è quello di mettere un ispezionabile calcolata proprietà di fronte del valore che si desidera impostare. Naturalmente, ancora non magicamente appaiono come un pop-up menu di valori enumerati in Interface Builder, ma almeno si può definire un ispezionabile valore da utilizzare per impostare un enum.
  • Al WWDC di quest’anno, ho chiesto ad un Apple ingegnere Sviluppatore di Strumenti di laboratorio su questo. Ha detto che ha accettato sarebbe una grande caratteristica, ma non è attualmente possibile. Lui mi ha suggerito di file di un radar a bugreport.apple.com che ho fatto. È stato chiuso come un duplicato del problema 15505220 ma mi raccomando mettere le persone in questioni simili. Queste cose spesso affrontato se un numero sufficiente di persone che si lamentano.
  • come è questa domanda diversa da stackoverflow.com/questions/27432736/…
  • Possibile duplicato di Come creare un IBInspectable di tipo enum
  • E con SwiftUI e la nuova Tela in Xcode 11, sembra che questo non sarà mai sulla Mela tabella di marcia

 

7 Replies
  1. 26

    Che non è possibile (per ora). È possibile utilizzare solo quei tipi che si vedono in Definito dall’Utente Runtime Attributi sezione.

    Da Apple doc:

    È possibile collegare il IBInspectable attributo di qualsiasi proprietà in una dichiarazione di classe, estensione della classe o categoria per qualsiasi tipo supportato da Interface Builder definito runtime attributi booleani, interi o in virgola mobile numero, stringa, stringa localizzata, il rettangolo, il punto, la dimensione, il colore, gamma, e nil.

    • Quando voglio utilizzare un enum, mi dia i valori enum esplicito assegnazioni ( = 1, = 2, etc.). E nel gestore, aggiungo un’asserzione se il valore di IB non è uno dei valori enum. Fastidioso che enumerazioni non sono supportati, ma questo trucco rende più fruibile, almeno.
    • Un enum è un numero intero.
    • Ancora non è possibile in Xcode 6.3.1 di utilizzare i tipi enum…
    • O in Xcode 8.3.2
    • siamo ancora in attesa in Xcode 9
  2. 22

    Un’altra soluzione per questo è di alterare il modo di una proprietà di enumerazione sembra interface builder. Per esempio:

    #if TARGET_INTERFACE_BUILDER
    @property (nonatomic, assign) IBInspectable NSInteger fontWeight;
    #else
    @property (nonatomic, assign) FontWeight fontWeight;
    #endif

    Questo presuppone un enum chiamato FontWeight. Esso si basa sul fatto che le enumerazioni e le materie prime di valori interi può essere utilizzato un po ‘ in modo intercambiabile in Objective-C. Dopo aver fatto questo, è possibile specificare un numero intero in Interface builder per la proprietà che non è l’ideale, ma funziona, e conserva una piccola quantità di tipo di sicurezza quando si utilizza la stessa struttura a livello di programmazione.

    Questa è un’alternativa migliore rispetto a dichiarare separata proprietà di tipo integer, perché non c’è bisogno di scrivere extra logica per gestire un secondo numero di proprietà che potrebbero essere utilizzati anche per realizzare la stessa cosa.

    Tuttavia, questo non funziona con Swift, perché non siamo in grado di eseguire il cast implicito da un numero intero di un enum. Ogni pensiero sulla soluzione che sarebbe apprezzato.

    • Ho davvero pensato che questo ha fatto il lavoro in Swift, ma ulteriori test… no
  3. 7

    Eseguire questa operazione utilizzando un Ispezionabile NSInteger valore e ignorare il setter per consentire di impostare il enum. Questo ha la limitazione di non utilizzo di un elenco a comparsa e se si cambia i valori enum, quindi le opzioni di interfaccia non aggiornate.

    Esempio.

    Nel File Di Intestazione:

    typedef NS_ENUM(NSInteger, LabelStyle)
    {
        LabelStyleContent = 0, //Default to content label
        LabelStyleHeader,
    };
    
    ...
    
    @property LabelStyle labelStyle;
    @property (nonatomic, setter=setLabelAsInt:) IBInspectable NSInteger labelStyleLink;

    Nel file di implementazione:

    - (void)setLabelAsInt:(NSInteger)value
    {
        self.labelStyle = (LabelStyle)value;
    }

    Si potrebbe aggiungere eventualmente un po ‘ di logica per assicurarsi che sia impostata su un valore valido

    • Non so perché questo è stato il basso votato. Mi sembra un buon modo per aggirare il problema.
    • Grazie @Fogmeister – in realtà sto usando questa implementazione all’interno di un’app, al momento 🙂
  4. 1

    Come @sikhapol risposto, questo non è possibile. La soluzione che uso per questo è di avere un sacco di IBInspectable bools nella mia classe e selezionare solo uno in interface builder. Per una maggiore sicurezza che di più non sono insieme, aggiungere un NSAssert nel setter per ogni uno.

    - (void)setSomeBool:(BOOL)flag
    {
        if (flag)
        {
            NSAssert(!_someOtherFlag && !_someThirdFlag, @"Only one flag can be set");
        }
    }

    Questo è un po ‘noioso e un po’ sciatta, IMO, ma è l’unico modo per ottenere questo tipo di comportamento a cui posso pensare,

  5. 1

    Voglio aggiungere che gli identificatori di un enum non sono disponibili al runtime per chiunque in Objective-C. Così, non ci può essere la possibilità di visualizzare ovunque.

  6. 1

    La mia soluzione era fare :

    @IBInspectable  
    var keyboardType = UIKeyboardType.default.rawValue {
            didSet { 
                 textField.keyboardType = UIKeyboardType(rawValue: keyboardType)! 
            }
    }

    Su IB, è necessario impostare un int in keyboardType campo

  7. 1

    Sikhapol è corretto, enumerazioni non sono ancora supportate anche non in xCode 9. Credo che l’approccio più sicuro è quello di utilizzare le enumerazioni come stringhe e implementare un ‘ “ombra” (privato) IBInspectable var. Ecco un esempio di un BarBtnPaintCode elemento che rappresenta un barbutton elemento che può essere in stile con un’icona personalizzata (che è fatto utilizzando PaintCode) proprio all’interno di Interface Builder (swift 4).

    Nell’interfaccia di costruire è sufficiente inserire la stringa (identico al valore di enumerazione), che mantiene in chiaro (se si immettono i numeri che nessuno sa cosa vogliono dire)

    class BarBtnPaintCode: BarBtnPaintCodeBase {
    
        enum TypeOfButton: String {
            case cancel
            case ok
            case done
            case edit
            case scanQr
            //values used for tracking if wrong input is used
            case uninitializedLoadedFromStoryboard
            case unknown
        }
    
        var typeOfButton = TypeOfButton.uninitializedLoadedFromStoryboard
    
        @IBInspectable private var type : String {
            set {
                typeOfButton = TypeOfButton(rawValue: newValue) ?? .unknown
                setup()
            }
            get {
                return typeOfButton.rawValue
            }
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            setup()
        }
    
        init(typeOfButton: TypeOfButton, title: String? = nil, target: AnyObject?, action: Selector) {
            super.init()
            self.typeOfButton = typeOfButton
            setup()
            self.target = target
            self.action = action
            self.title  = title
        }
    
        override func setup() {
            //same for all
            setTitleTextAttributes([NSAttributedStringKey.font : UIFont.defaultFont(size: 15)],for: UIControlState.normal)
            //depending on the type
            switch typeOfButton {
            case .cancel  :
                title = nil
                image = PaintCode.imageOfBarbtn_cancel(language: currentVisibleLanguage)
            case .ok      :
                title = nil
                image = PaintCode.imageOfBarbtn_ok(language: currentVisibleLanguage)
            case .done    :
                title = nil
                image = PaintCode.imageOfBarbtn_done(language: currentVisibleLanguage)
            case .edit    :
                title = nil
                image = PaintCode.imageOfBarbtn_edit(language: currentVisibleLanguage)
            case .uninitializedLoadedFromStoryboard :
                title = nil
                image = PaintCode.imageOfBarbtn_unknown
                break
            case .unknown:
                log.error("BarBtnPaintCode used with unrecognized type")
                title = nil
                image = PaintCode.imageOfBarbtn_unknown
                break
            }
    
        }
    
    }
    • Fantastica soluzione, realizzata con Swift 4 senza problemi. se si utilizza questa attenzione di ortografia tipi correttamente in storyboard e xibs

Lascia un commento