Xcode6之后苹果就一直极力倡导使用
storyboard
,特别随着Xcode6 的Size Class
和IBDesignable
、IBInspectable
;Xcode7 的Storyboard Reference
推出之后,越来越多的开发者开始使用Storyboard
。作为一个Storyboard
的重度使用者,在这里对使用Storyboard
的一些特性和技巧做一些整理。
Storyboard Reference
作为xib和storyboard的重度使用者(特别是Xcode6以后),以前storyboard一直被大家吐槽,特别是多人开发
Merge
的时候,一大堆warning
、error
扑面而来,弄得头都大。而Xcode7之后出现的Storyboard Reference,让我为之一喜。
Storyboard Reference的目的是把一个个模块分离,既避免了Main.storyboard
的庞大不可把控,又模块化UI让分工变得简单,而且可以快速准确地找到分工的各部分。
使用Storyboard Reference
,最后你看到你的storyboard应该是这样的:
这样是不是简洁明了,可控性好很多,不用再为多人开发整合而烦恼了~ ~
操作:
只需在
Main.storyboard
中选中要分离的UIViewController
,然后点击菜单:Editor->Refactor to Storyboard 创建一个新的分离出来的storyboard就好了。
Size Class
Xcode6之后出现的Size Class
,下面显示了iOS设备及其对应的Size Class:
更直观的iOS设备对应的Size Class:
至于size class在各设备上的相对应的使用就不赘述了,接下来介绍size class
在Attributes Inspector
上的使用:
Attributes Inspector
中左边带+
的都可以使用size class
.
IBDesignable&IBInspectable
IBDesignable
&IBInspectable
的介绍在nshipster中很早之前就有了,这里也只是我之前使用过的一些整理。
比如,在Storyboard中给按钮加圆角、边框什么的,User Defined Runtime Attributes
可能是这个样子的:
上图是用户自定义的运行时属性的使用,而IBInspectable
属性提供了一种新的方式。
创建一个自定义的UIButton
:
.h文件
#import
IB_DESIGNABLE
@interface MyDrawButton : UIButton
@property (nonatomic) IBInspectable UIColor *fillColor; //填充颜色
@property (nonatomic) IBInspectable NSInteger lineWidth; //线的宽度
@property (nonatomic) IBInspectable NSInteger cornerRadius; //圆角弧度
@property (nonatomic) IBInspectable NSInteger borderWidth; //边框宽度
@end
.m文件
#import "MyDrawButton.h"
#import
@implementation MyDrawButton
- (void)drawRect:(CGRect)rect {
CGContextRef context=UIGraphicsGetCurrentContext();
CGRect myFrame=self.bounds;
CGContextSetLineWidth(context, _lineWidth);
CGRectInset(myFrame, 5, 5);
[_fillColor set];
UIRectFrame(myFrame);
self.layer.cornerRadius=_cornerRadius;
self.layer.borderWidth=_borderWidth;
self.layer.borderColor=_fillColor.CGColor;
[self addTarget:self action:@selector(scaleToSmall)
forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragEnter];
[self addTarget:self action:@selector(scaleAnimation)
forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:@selector(scaleToDefault)
forControlEvents:UIControlEventTouchDragExit];
}
- (void)scaleToSmall
{
POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(0.95f, 0.95f)];
[self.layer pop_addAnimation:scaleAnimation forKey:@"layerScaleSmallAnimation"];
}
- (void)scaleAnimation
{
POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.velocity = [NSValue valueWithCGSize:CGSizeMake(2.f, 2.f)];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
scaleAnimation.springBounciness = 25.0f;
[self.layer pop_addAnimation:scaleAnimation forKey:@"layerScaleSpringAnimation"];
}
- (void)scaleToDefault
{
POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
[self.layer pop_addAnimation:scaleAnimation forKey:@"layerScaleDefaultAnimation"];
}
@end
storyboard中的UIButton
只需继承自它,然后就可以在Attributes Inspector
中看到这些属性:
给相应的属性设值就有效果了。而上面给自定义按钮添加了点击动画
,只要继承自这个自定义按钮都会有点击动画,其效果是这样的:
User Defined Runtime Attributes
上面图中最后两个是自定义关联的运行时属性,
比如layer.colorFromUIColor
,只需新建一个CALayer
的Category
:
.h文件
@interface CALayer (Addition)
@property(nonatomic,strong) UIColor *colorFromUIColor;
-(void)setColorFromUIColor:(UIColor *)color;
@end
.m文件
#import "CALayer+Addition.h"
#import
@implementation CALayer (Addition)
@dynamic colorFromUIColor;
-(UIColor *)colorFromUIColor
{
return objc_getAssociatedObject(self, @selector(colorFromUIColor));
}
-(void)setColorFromUIColor:(UIColor *)color
{
objc_setAssociatedObject(self, @selector(colorFromUIColor), color, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self setColorFromUI:self.colorFromUIColor];
}
-(void)setColorFromUI:(UIColor *)color
{
self.borderColor=color.CGColor;
}
@end
这样设置就ok了,然后在User Defined Runtime Attributes
中就可以设置colorFromUIColor
这个属性了。
而自定义runtime属性bindingAnimationType
来自FastAnimationWithPOP,配置相关属性运行可以直接得到如下效果:
配置:
导入pop
、FastAnimationWithPOP
:
pod 'pop', '~> 1.0.9'
pod 'FastAnimationWithPOP', '~> 0.0.2'
然后在Identity Inspector
中配置控件的用户自定义运行时属性
:
控制好animationType
和delay
就得到了上面的效果,自己不需要写一句代码!有没有很nice! 反正我最开始用的时候兴奋极了 ~ ~
UIStackView
iOS9之后出来的
UIStackView
比较特别,对于自动布局这块非常方便,它可以快速地在垂直或水平排布多个subview,最有用的就是它会自动为每个subview创建和添加Auto Layout constraints。当然你可以控制subview的大小和位置。可以通过选项配置subview的大小、排布以及彼此间的间距。具体细节见iOS 9: UIStackView入门,以下是我自己实战操作。
至于兼容iOS9之前版本,推荐使用FDStackView,兼容UIStackView iOS9之前版本,同样的,也可以使用storyboard
,非常好!
FDStackView Part1、FDStackView Part2、FDStackView Part3这三篇文章是作者分析FDStackView
的设计实现过程,有兴趣可以看一下。
提高Interface Builder高效工作的8个技巧
- 使view的Size与view中的Content相适应
- 按住option键—观察所选中view与另外view边缘之间的距离
- Editor -> Embed In View, Unembed:
- 在不影响subview的位置时给view自由的添加padding
- 对不在最前端的view进行移动
- IBOutletCollection排序
- 使用自定义属性
- MoarFonts——字体定制:所见即所得
具体细节查看原文:提高Interface Builder高效工作的8个技巧
总结:
我现在一直在使用storyboard
,至今感觉良好!特别有了这些技巧和特性之后,效率那是杠杠的.。这里把以前用过的写在这里分享☺出来,也方便我自己总结和回顾。
这篇文章主要内容:
- Storyboard Reference:Storyboard分离
- Size Class:多设备自动布局
- IBDesignable&IBInspectable:配置自定义控件
- User Defined Runtime Attributes:用户自定义运行时属性
- UIStackView:方便垂直或水平排布多个subview
- 提高Interface Builder高效工作的8个技巧:Interface Builder的操作技巧