Подтвердить что ты не робот

Определенные пользователем атрибуты времени выполнения (IBInspectable), установленные после заданных атрибутов?

Я хочу добавить новый атрибут IBInspectable (вычисляемое свойство) в UILabel с помощью метода категории. В идеале я хочу, чтобы этот атрибут устанавливался после того, как текст меток задан (через setValue: forKey), так как этот атрибут IBInspectable может привести к обновлению текста UILabels, и мы не хотим, чтобы текст в UILabel заменялся позже Это. Если посмотреть на документацию, нет никаких упоминаний о том, что предварительно определенные атрибуты всегда устанавливаются перед пользовательскими атрибутами во время загрузки nib/storyboard для атрибутов, настроенных в Interface Builder.

Пользовательские атрибуты добавляются к объекту в Interface Builder с использованием IBInspectable или пользовательских атрибутов времени выполнения, которые, как гарантируется, будут установлены после стандартных заданных свойств/атрибутов объектов?

4b9b3361

Ответ 1

В следующем эксперименте делается вывод о том, что свойство собственного текста задано до свойства категории, поэтому значение можно безопасно перезаписать установщиком категории.

Категория ярлыков:

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

В IB установите свойство проверяемой категории и свойство текста....

введите описание изображения здесь

Небольшая аппаратура в контроллере с открытым представлением:

- (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);
}

Запустите его, а выход NSLog указывает, что во время пробуждения от nib собственное свойство устанавливается к тому времени, когда вызывается свойство setter...

... [794: 41622], устанавливая thingy на "thingy value", мой текст в настоящее время "текстовое значение"

... [794: 41622] didload text - это "текстовое значение" , а thingy - значение "thingy"

... [794: 41622] willappear text - это "текстовое значение" , а thingy - "вещь"

Настройка свойства текста метки в элементе настройки свойства категории (и, я проверял его) приводит к тому, что свойство text будет перезаписано в свойство thingy, так как сначала свойство initialize инициализируется.

Другие доказательства можно увидеть в файле XIB при визуализации в виде 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>

..., который согласуется с тем, как создается экземпляр и инициализируется через предварительный обход, тем самым устанавливая свойства метки (родительского тега) перед (дочерним тегом) userDefinedRuntimeAttributes.

Ответ 2

Если вы создаете расширение с компьютерной переменной IBInspectable, значение, помещенное в это настраиваемое поле в Interface Builder, переопределит значение в текстовом поле метки, когда оба значения будут установлены в Interface Builder, хотя он не будет просматривать этот способ в Interface Builder.

extension UILabel {

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

        set {
            text = newValue
            setNeedsDisplay()
        }
    }

}

Конструктор интерфейсов введите описание изображения здесь