2016-09-05 44 views
11

Chciałbym dodać nowy atrybut IBInspectable (obliczona właściwość) do UILabel za pomocą metody kategorii. Idealnie chcę, aby ten atrybut był ustawiony po ustawieniu tekstu etykiety (przez wartość setValue: forKey), ponieważ ten atrybut IBInspectable może spowodować aktualizację tekstu UILabels i nie chcemy, aby tekst w wersji UILabel został później zastąpiony. Patrząc na dokumentację nie ma żadnej wzmianki, czy predefiniowane atrybuty są zawsze ustawione przed atrybutami zdefiniowanymi przez użytkownika podczas ładowania atrybutów skonfigurowanych w Konstruktorze interfejsu.Zdefiniowane przez użytkownika atrybuty środowiska wykonawczego (IBInspectable) ustawione po predefiniowanych atrybutach?

Czy atrybuty niestandardowe zostały dodane do obiektu w Konstruktorze interfejsów przy użyciu IBInspectable lub Atrybuty środowiska wykonawczego zdefiniowane przez użytkownika, które mają być ustawione po standardowych predefiniowanych właściwościach/atrybutach obiektów?

+0

Czy możesz być bardziej jasne, jeśli tekst etykiety jest ustawiany programowo (jak w viewDidLoad) lub masz na myśli ustawić w IB? –

+0

Niestety oba są ustawione przez IB – bencallis

Odpowiedz

0

Jeśli utworzysz rozszerzenie ze zmienną komputerową IBInspectable, wartość umieszczona w tym polu niestandardowym w Konstruktorze interfejsów zastąpi wartość w polu tekstowym etykiety, gdy obie wartości zostaną ustawione w Konstruktorze interfejsu, nawet jeśli nie będzie podglądu tego sposób w konstruktorze interfejsów.

extension UILabel { 

    @IBInspectable var value: String? { 
     get { 
      return text 
     } 

     set { 
      text = newValue 
      setNeedsDisplay() 
     } 
    } 

} 

Interface builder enter image description here

+0

Dzięki za odpowiedzi. Zaimplementowałem podobne rozszerzenie i przetestowałem je na różnych wersjach systemu iOS, które zauważyłem tak samo. Jednak; Miałem nadzieję, że zostało to gdzieś udokumentowane, więc mogłem być całkowicie bezpieczny używając go w kodzie produkcyjnym. – bencallis

2

Poniższy eksperyment stwierdza, że ​​rodzimy nieruchomość tekst jest ustawiony przed własności kategorii, a więc wartość można bezpiecznie nadpisane kategorii seter.

A Kategoria label:

// UILabel+Thingy.h 

#import <UIKit/UIKit.h> 

@interface UILabel (Thingy) 

@property (nonatomic, strong) IBInspectable NSString *thingy; 

@end 

// UILabel+UILabel_Thingy.m 

#import "UILabel+Thingy.h" 
#import <objc/runtime.h> 

@implementation UILabel (Thingy) 

- (NSString *)thingy { 
    return objc_getAssociatedObject(self, @selector(thingy)); 
} 

- (void)setThingy:(NSString *)thingy { 
    NSLog(@"setting thingy to '%@', my text is currently '%@'", thingy, self.text); 
    objc_setAssociatedObject(self, @selector(thingy), thingy, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 

@end 

w IB, należy ustawić właściwość kategorii podlegającej inspekcji i właściwość tekstu ....

enter image description here

Trochę oprzyrządowania zawierającego kontroler widoku:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSLog(@"didLoad text is '%@' and thingy is '%@'", self.label.text, self.label.thingy); 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    NSLog(@"willAppear text is '%@' and thingy is '%@'", self.label.text, self.label.thingy); 
} 

Uruchom, a wynik indeksu NSLog miej- scu, że podczas przebudzony ze stalówką, właściwość rodzimy jest ustawiony przez czas własność kategoria seter nazywa ...

... [794: 41622] ustawienie thingy „value” cienias, mój tekst jest obecnie 'wartość tekst'

... [794: 41622] tekst didload jest 'wartość tekst' i thingy jest 'wartość thingy'

... [794: 41622] tekst willappear jest 'wartość tekst' i jest "rzeczywista wartość"

Ustawianie właściwości tekstu etykiety w ca Narzędzie ustawiające właściwość tegory (i przetestuje ją) powoduje, że właściwość text jest nadpisywana do właściwości thingy, ponieważ właściwość text jest inicjowana jako pierwsza.

Dalsze dowody można zobaczyć w pliku XIB gdy renderowane jako XML ...

<label opaque="NO" (... all the native properties) text="text value" (...) id="XAM-6h-4fn"> 
    <rect key="frame" x="274" y="147" width="278" height="34"/> 

    (... and so on) 

    <userDefinedRuntimeAttributes> 
     <userDefinedRuntimeAttribute type="string" keyPath="thingy" value="thingy value"/> 
    </userDefinedRuntimeAttributes> 
</label> 

... która jest zgodna z poglądem jest instancja i zainicjowany przez pre-order przechodzenie, a tym samym ustawianie właściwości etykiety (nadrzędny znacznik) przed tagiem (child tag) userDefinedRuntimeAttributes.

+0

Dzięki za odpowiedź. Podczas testów na różnych wersjach systemu iOS zauważyłem to samo zachowanie. Jednak; Miałem nadzieję, że zostało to gdzieś udokumentowane, więc mogłem być całkowicie bezpieczny używając go w kodzie produkcyjnym. – bencallis

+0

Wygląda na to, że nie jest on objęty jawnie tam, gdzie należałoby go zobaczyć w dokumentach. Ale zademonstrowane deterministyczne zachowanie jest lepsze niż doc, prawda? Tak długo, jak używa 100% publicznych interfejsów API, zachowanie może być traktowane jako stałe w aplikacji jako jakakolwiek część pakietu SDK. – danh

+0

Sądzę, że w przyszłej wersji systemu iOS pojawi się obawa, że ​​zamówienie zostanie zmienione bez zauważalnej zmiany interfejsu API. – bencallis