IBOutletCollection

IBOutletCollection

IBOutletCollection

When connecting IB with related files, we often use two keywords: IBOutlet and IBAction. Those who often use xib or storyboard should be very familiar with these two keywords. However, UIKit also provides another pseudo keyword IBOutletCollection. With this keyword, we can connect a group of identical controls on the interface to the same array .

Let's first look at the definition of this pseudo keyword. You can find the following definition from the header file UINibDeclarations.h of UIKit.framework:

  1. #ifndef IBOutletCollection
  2. #define IBOutletCollection(ClassName)
  3. #endif

In addition, in the Clang source code, there is a safer definition method, as shown below:

  1. #define IBOutletCollection(ClassName) __attribute__((iboutletcollection(ClassName)))

From the above definition, you can see that, unlike IBOutlet, IBOutletCollection takes a parameter, which is a class name.

Normally, when we use an IBOutletCollection property, the property must be strong and of type NSArray, as shown below:

  1. @property (strong, nonatomic) IBOutletCollection(UIScrollView) NSArray *scrollViews;

Assuming that there are three horizontal scrollViews in our xib file, we can connect all three scrollViews to the scrollViews property, and then we can do some unified processing in our code, as shown below:

  1. - ( void )setupScrollViewImages
  2. {
  3. for (UIScrollView *scrollView in self.scrollViews) {
  4. [self.imagesData enumerateObjectsUsingBlock:^(NSString *imageName, NSUInteger idx, BOOL *stop) {
  5. UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetWidth(scrollView.frame) * idx, 0 , CGRectGetWidth(scrollView.frame), CGRectGetHeight(scrollView.frame))];
  6. imageView.contentMode = UIViewContentModeScaleAspectFill;
  7. imageView.image = [UIImage imageNamed:imageName];
  8. [scrollView addSubview:imageView];
  9. }];
  10. }
  11. }

This code will affect three scrollViews. The advantage of doing this is that we don't need to manually add the scrollView to the scrollViews through the addObject: method.

However, when using IBOutletCollection, you need to pay attention to two points:

The order of objects in an IBOutletCollection is undefined. We can see from the debugger that the order of objects in the collection is the same as the order in which we connected them. But this order may vary between versions of Xcode. So we should not try to assume this order in our code.

No matter what the control in IBOutletCollection(ClassName) is, the type of the property is always NSArray. In fact, we can declare any type, such as NSSet, NSMutableArray, or even UIColor, but no matter what class we set here, the IBOutletCollection property always points to an NSArray array.

Regarding the second point, let's take the scrollViews above as an example and make the following changes:

  1. @property (strong, nonatomic) IBOutletCollection(UIScrollView) NSSet *scrollViews;

In fact, when we print this scrollViews in the console, the result is as follows:

  1. (lldb) po self.scrollViews
  2. <__NSArrayI 0x1740573d0 >(
  3. <UIScrollView: 0x12d60d770 ; frame = ( 0   0 ; 320   162 ); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1740574f0 >; layer = <CALayer: 0x174229480 >; contentOffset: { 0 , 0 }; contentSize: { 0 , 0 }>,
  4. <UIScrollView: 0x12d60dee0 ; frame = ( 0   0 ; 320   161 ); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x174057790 >; layer = <CALayer: 0x1742297c0 >; contentOffset: { 0 , 0 }; contentSize: { 0 , 0 }>,
  5. <UIScrollView: 0x12d60e650 ; frame = ( 0   0 ; 320   163 ); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1740579a0 >; layer = <CALayer: 0x1742298e0 >; contentOffset: { 0 , 0 }; contentSize: { 0 , 0 }>
  6. )

As you can see, it points to an NSArray array.

In addition, IBOutletCollection actually existed in iOS 4. However, Objective-C now supports object literals, so you can define arrays directly with @[], which is much more convenient. And object literals can add views defined in code that are not in the xib, so it is more flexible. Of course, which of the two methods to choose depends on our actual needs and preferences.

refer to

IBAction / IBOutlet / IBOutletCollection

IBOutletCollection.m

<<:  When should I use copy and when should I use strong for NSString attributes?

>>:  Different ways to implement locks in Objective-C (Part 2)

Recommend

Pinduoduo activities attract new growth matrix!

From time to time, you can see some screen-sweepi...

Slime, which doesn't even have a brain, can actually plan city routes

You must be familiar with slimes. Their names oft...

Review of H5 fission growth case, 20,000 followers increased in 22 hours!

Every time there is a holiday, every time a star ...

Interesting Facts: How does your cat choose the person he likes?

If you have a cat and there are many other family...

CES2015: ZTE releases 6-inch ultra-large screen mobile phone Grand X Max+

On January 6, 2015, Beijing time, ZTE Mobile Comm...

How to get more recommendations on self-media platforms?

This article will talk to you about the article r...

Singing light bulb Sengled Pulse Flex music smart light review

With the increasing popularity of the Internet of...

Because I saw something strange, my memory before the age of 3 was deleted?

If I think about it carefully, the first time I h...

Itching, itching, itching and peeling may also be cancer?

Review expert: Zhang Yuhong, chief physician of t...