某种“全球”的IBDesignables?

在故事板中有一个UIView,约束例如“0.1”比例高度。

想象一下,在许多不同的场景中,你有一个类似的约束“0.1”。

假设你想将0.1的值改为0.975。

你必须随时随地改变它。

有什么方法可以使用@IBInspectable和/或约束来创build一种“全局值”

这样你就可以一次把它们全部改变 ,并在故事板中一次查看结果。

(当然,在运行的时候,你可以用代码来传播,但最好在故事板上看到。)


请注意,例如,Wain的解决scheme完美地工作:您可以设置一次的值,并影响到应用程序的任何地方。 但不幸的是,它只能在运行时间,而不是在故事板上看到它。

我没有尝试过,这只是在这里input,所以借口拼写错误,但我会考虑在NSLayoutConstraint创build一个扩展,沿线的东西:

 let constants = [ "bannerHeight" : CGFloat(50) ] extension NSLayoutConstraint { func setCommonConstant(name: String) { self.constant = constants[name]! } } 

然后在Xcode中使用用户定义的运行时属性,以便指定要使用的名称:

 commonConstant, type String, value name 

所以,就像这样,在故事板上的每个约束条件中:

在这里输入图像说明

我想不出一种方法来让IB在devise时更新所有的“实例”,当一个实例的属性值发生变化时(我认为这通常是不希望的和非标准的行为)。 我相当肯定它不能完成,因为我不认为IB在IB会话期间在内存中保留了一个自定义视图的实例。 我认为它是做实例化的视图,设置属性,快照渲染,然后释放它。

应该可以设置属性来设置未来的视图实例所使用的“默认”值。 我们可以通过在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中的所有“实例”)。 要做到这一点,你可能必须使用上面的技术,并将其扩展为在视图中的自定义initWithCoder:方法中包含代码。

也许可能会变得非常棘手,并试图“触摸”正在编辑的xib文件,这可能会提示IB重新加载?

当我开始使用Storyboard和Interface Builder开发时,我试图find类似的东西。 不幸的是,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 } } } 

这可能是一个起点。 希望能帮助到你