IBOutletCollection
在IB与相关文件做连接时,我们经常会用到两个关键字:IBOutlet 和 IBAction。经常用 xib或storyboard的童鞋应该用这两上关键字非常熟悉了。不过UIKit还提供了另一个伪关键字IBOutletCollection,我们使用这个关键字,可以将界面上一组相同的控件连接到同一个数组中。
我们先来看看这个伪关键字的定义,可以从UIKit.framework的头文件UINibDeclarations.h找到如下定义:
#ifndef IBOutletCollection
#define IBOutletCollection(ClassName)
#endif
另外,在Clang源码中,有更安全的定义方式,如下所示:
#define IBOutletCollection(ClassName) __attribute__((iboutletcollection(ClassName)))
从上面的定义可以看到,与IBOutlet不同的是,IBOutletCollection带有一个参数,该参数是一个类名。
通常情况下,我们使用一个IBOutletCollection属性时,属性必须是strong的,且类型是NSArray,如下所示:
@property (strong, nonatomic) IBOutletCollection(UIScrollView) NSArray *scrollViews;
假定我们的xib文件中有三个横向的scrollView,我们便可以将这三个scrollView都连接至scrollViews属性,然后在我们的代码中便可以做一些统一处理,如下所示:
- (void)setupScrollViewImages
{
for (UIScrollView *scrollView in self.scrollViews) {
[self.imagesData enumerateObjectsUsingBlock:^(NSString *imageName, NSUInteger idx, BOOL *stop) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetWidth(scrollView.frame) * idx, 0, CGRectGetWidth(scrollView.frame), CGRectGetHeight(scrollView.frame))];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.image = [UIImage imageNamed:imageName];
[scrollView addSubview:imageView];
}];
}
}
这段代码会影响到三个scrollView。这样做的好处是我们不需要手动通过addObject:方法将scrollView添加到scrollViews中。
不过在使用IBOutletCollection时,需要注意两点:
IBOutletCollection集合中对象的顺序是不确定的。我们通过调试方法可以看到集合中对象的顺序跟我们连接的顺序是一样的。但是这个顺序可能会因为不同版本的Xcode而有所不同。所以我们不应该试图在代码中去假定这种顺序。
不管IBOutletCollection(ClassName)中的控件是什么,属性的类型始终是NSArray。实际上,我们可以声明是任何类型,如NSSet, NSMutableArray,甚至可以是UIColor,但不管我们在此设置的是什么类,IBOutletCollection属性总是指向一个NSArray数组。
关于第二点,我们以上面的scrollViews为例,作如下修改:
@property (strong, nonatomic) IBOutletCollection(UIScrollView) NSSet *scrollViews;
实际上我们在控制台打印这个scrollViews时,结果如下所示:
(lldb) po self.scrollViews(,,)
可以看到,它指向的是一个NSArray数组。
另外,IBOutletCollection实际上在iOS 4版本中就有了。不过,现在的Objective-C已经支持object literals了,所以定义数组可以直接用@[],方便了许多。而且object literals方式可以添加不在xib中的用代码定义的视图,所以显得更加灵活。当然,两种方式选择哪一种,就看我们自己的实际需要和喜好了
转自:这里
IBInspectable和IB_DESIGNABLE
在做应用的UI设计的时候,如果属性能够在Interface Builder的图形化界面进行设置,并且动态的预览到效果,那样无疑会大大提高应用的开发效率。而XCode为我们提供了这样的一种方式,就是使用IBInspectable和IB_DESIGNABLE
例如为imageView的继承类设置cornerRadius
头文件添加属性
@property (nonatomic) IBInspectable CGFloat cornerRadius;
-(void)setCornerRadius:(CGFloat)cornerRadius{
_cornerRadius = cornerRadius;
self.layer.cornerRadius = cornerRadius;
self.layer.masksToBounds = cornerRadius > 0?true:false;
}
这样,在Attribute Inspector就会多出一个配置选项
在.h文件#import 后面加入 IB_DESIGNABLE 可实时预览效果哦
Ps:转载自这里