IBDesignables 的某种 "global"?
Some sort of "global" for IBDesignables?
在情节提要中有一个 UIView,具有例如“0.1”比例高度的约束。
假设您对许多不同场景中的视图有类似的约束“0.1”。
假设您要将值 0.1 更改为 0.975。
你必须在每个地方单独更改它。
有什么方法可以使用@IBInspectable and/or 约束来进行某种 "global value" 排序吗?
这样您就可以一次性更改所有内容,并一次性查看所有结果在情节提要。
(当然,在 运行-time 你可以在代码中传播这些。但最好在故事板上看到它。)
请注意,例如,Wain 的以下解决方案非常有效:您可以设置一次值,并影响应用程序中的所有位置。但不幸的是,它只在 运行 时这样做,你不会在故事板上看到它。
我没试过,只是在这里输入,请原谅打字错误,但我会考虑在 NSLayoutConstraint
上创建一个扩展,类似于:
let constants = [
"bannerHeight" : CGFloat(50)
]
extension NSLayoutConstraint {
func setCommonConstant(name: String) {
self.constant = constants[name]!
}
}
然后在 Xcode 中使用用户定义的运行时属性,因此指定要使用的名称:
commonConstant, type String, value name
所以,就像这样,在情节提要中的任何地方的每个约束上:
当我开始使用 Storyboard 和 Interface Builder 进行开发时,我试图找到类似的东西。不幸的是,xCode 的可扩展性不强,使用 Interface Builder 的代码集中化无法像在 Android 开发中那样轻松实现。
您可以尝试这样的操作,在 UIView 扩展中使用自定义 @IBDesignable 属性并更改约束值或在运行时添加约束(但我不知道它是否也会影响 Interface Builder):
extension UIView {
@IBInspectable var insertTopConstraint: Bool {
set {
// suppose 10 is your fixed value
addConstraint(NSLayoutConstraint(item: self, attribute: .Top, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 10))
updateConstraintsIfNeeded() // could be useful..
}
get {
return true
}
}
}
这可能是一个起点。希望对你有帮助
当单个实例发生 属性 值更改时,我想不出一种方法让 IB 在设计时更新所有 "instances"(而且我认为这通常是不希望的,也不是-标准行为)。我相当肯定它无法完成,因为我认为 IB 不会在 IB 会话期间在内存中保留您的自定义视图的实例。我认为它所做的是实例化视图,为其设置属性,对其进行快照以进行渲染,然后释放它。
应该可以设置设置 "default" 值的属性,以供视图的未来实例使用。我们可以通过在 NSUserDefaults
(XCode's) 中存储 "default" 值,并读取 initWithFrame:
中的默认值来实现这一点,IB 将调用它来初始化一个新实例。我们可以使用 #if TARGET_INTERFACE_BUILDER
关闭所有这些默认内容,这样它就不会在运行时显示在设备上。
IB_DESIGNABLE
@interface CoolView : UIView
@property (strong, nonatomic) IBInspectable UIColor* frameColor;
#if TARGET_INTERFACE_BUILDER
@property (strong, nonatomic) IBInspectable UIColor* defaultFrameColor;
#endif
@end
@implementation CoolView
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame: frame];
if ( self != nil ) {
#if TARGET_INTERFACE_BUILDER
NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey: @"defaultCoolViewFrameColor"];
if ( colorData != nil ) {
self.frameColor = [NSKeyedUnarchiver unarchiveObjectWithData: colorData];;
}
#endif
}
return self;
}
- (void) drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 10);
CGRect f = CGRectInset(self.bounds, 10, 10);
[self.frameColor set];
UIRectFrame(f);
}
#if TARGET_INTERFACE_BUILDER
- (void) setDefaultFrameColor:(UIColor *)defaultFrameColor
{
_defaultFrameColor = defaultFrameColor;
NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject: defaultFrameColor];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"defaultCoolViewFrameColor"];
}
#endif
@end
如果您同意强制 IB 重新加载您的 xib/storyboard 文件,您可能会更接近您的原始目标(更新 IB 中的所有 "instances")。为此,您可能必须使用上述技术并将其扩展以在视图中的自定义 initWithCoder:
方法中包含代码。
可能你会变得非常棘手并尝试 "touch" 正在编辑的 xib 文件,这可能会提示 IB 重新加载?
在情节提要中有一个 UIView,具有例如“0.1”比例高度的约束。
假设您对许多不同场景中的视图有类似的约束“0.1”。
假设您要将值 0.1 更改为 0.975。
你必须在每个地方单独更改它。
有什么方法可以使用@IBInspectable and/or 约束来进行某种 "global value" 排序吗?
这样您就可以一次性更改所有内容,并一次性查看所有结果在情节提要。
(当然,在 运行-time 你可以在代码中传播这些。但最好在故事板上看到它。)
请注意,例如,Wain 的以下解决方案非常有效:您可以设置一次值,并影响应用程序中的所有位置。但不幸的是,它只在 运行 时这样做,你不会在故事板上看到它。
我没试过,只是在这里输入,请原谅打字错误,但我会考虑在 NSLayoutConstraint
上创建一个扩展,类似于:
let constants = [
"bannerHeight" : CGFloat(50)
]
extension NSLayoutConstraint {
func setCommonConstant(name: String) {
self.constant = constants[name]!
}
}
然后在 Xcode 中使用用户定义的运行时属性,因此指定要使用的名称:
commonConstant, type String, value name
所以,就像这样,在情节提要中的任何地方的每个约束上:
当我开始使用 Storyboard 和 Interface Builder 进行开发时,我试图找到类似的东西。不幸的是,xCode 的可扩展性不强,使用 Interface Builder 的代码集中化无法像在 Android 开发中那样轻松实现。
您可以尝试这样的操作,在 UIView 扩展中使用自定义 @IBDesignable 属性并更改约束值或在运行时添加约束(但我不知道它是否也会影响 Interface Builder):
extension UIView {
@IBInspectable var insertTopConstraint: Bool {
set {
// suppose 10 is your fixed value
addConstraint(NSLayoutConstraint(item: self, attribute: .Top, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 10))
updateConstraintsIfNeeded() // could be useful..
}
get {
return true
}
}
}
这可能是一个起点。希望对你有帮助
当单个实例发生 属性 值更改时,我想不出一种方法让 IB 在设计时更新所有 "instances"(而且我认为这通常是不希望的,也不是-标准行为)。我相当肯定它无法完成,因为我认为 IB 不会在 IB 会话期间在内存中保留您的自定义视图的实例。我认为它所做的是实例化视图,为其设置属性,对其进行快照以进行渲染,然后释放它。
应该可以设置设置 "default" 值的属性,以供视图的未来实例使用。我们可以通过在 NSUserDefaults
(XCode's) 中存储 "default" 值,并读取 initWithFrame:
中的默认值来实现这一点,IB 将调用它来初始化一个新实例。我们可以使用 #if TARGET_INTERFACE_BUILDER
关闭所有这些默认内容,这样它就不会在运行时显示在设备上。
IB_DESIGNABLE
@interface CoolView : UIView
@property (strong, nonatomic) IBInspectable UIColor* frameColor;
#if TARGET_INTERFACE_BUILDER
@property (strong, nonatomic) IBInspectable UIColor* defaultFrameColor;
#endif
@end
@implementation CoolView
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame: frame];
if ( self != nil ) {
#if TARGET_INTERFACE_BUILDER
NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey: @"defaultCoolViewFrameColor"];
if ( colorData != nil ) {
self.frameColor = [NSKeyedUnarchiver unarchiveObjectWithData: colorData];;
}
#endif
}
return self;
}
- (void) drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 10);
CGRect f = CGRectInset(self.bounds, 10, 10);
[self.frameColor set];
UIRectFrame(f);
}
#if TARGET_INTERFACE_BUILDER
- (void) setDefaultFrameColor:(UIColor *)defaultFrameColor
{
_defaultFrameColor = defaultFrameColor;
NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject: defaultFrameColor];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"defaultCoolViewFrameColor"];
}
#endif
@end
如果您同意强制 IB 重新加载您的 xib/storyboard 文件,您可能会更接近您的原始目标(更新 IB 中的所有 "instances")。为此,您可能必须使用上述技术并将其扩展以在视图中的自定义 initWithCoder:
方法中包含代码。
可能你会变得非常棘手并尝试 "touch" 正在编辑的 xib 文件,这可能会提示 IB 重新加载?