gpt4 book ai didi

ios - 在预定义属性之后设置用户定义的运行时属性(IBInspectable)?

转载 作者:技术小花猫 更新时间:2023-10-29 10:53:03 27 4
gpt4 key购买 nike

我想添加一个新的 IBInspectable属性(计算属性)到 UILabel通过类别方法。理想情况下,我希望在设置标签文本后设置此属性(通过 setValue:forKey),因为此 IBInspectable 属性可能会导致更新 UILabels 文本,而我们不希望 UILabel 中的文本稍后更换它。查看文档,没有提及在 nib/storyboard 期间预定义属性是否始终设置在用户定义属性之前加载在 Interface Builder 中配置的属性。

是否使用 IBInspectable 将自定义属性添加到 Interface Builder 中的对象?还是保证在标准预定义对象属性/属性之后设置用户定义的运行时属性?

最佳答案

以下实验得出结论, native 文本属性设置在类别属性之前,因此类别 setter 可以安全地覆盖该值。

标签类别:

//  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 中,设置可检查的类别属性和文本属性....

enter image description here

包含 View Controller 中的一些工具:

- (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 时设置了 native 属性...

...[794:41622] setting thingy to 'thingy value', my text is currently 'text value'

...[794:41622] didload text is 'text value' and thingy is 'thingy value'

...[794:41622] willappear text is 'text value' and thingy is 'thingy value'

在类别属性 setter 中设置标签的文本属性将(并且确实如此,我测试了它)导致文本属性被覆盖为 thingy 属性,因为文本属性首先被初始化。

当呈现为 XML 时,可以在 XIB 文件中看到更多证据...

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

...这与通过预序遍历实例化和初始化的 View 一致,从而在(子标签)userDefinedRuntimeAttributes 之前设置(父标签)标签属性。

关于ios - 在预定义属性之后设置用户定义的运行时属性(IBInspectable)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39327280/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com