32

I want to make an array with a bunch of UIImageViews I have in Interface Builder. Instead of having 20 or 30

IBOutlet UIImageView *img1;

and linking them all that way, and then putting them into an array, is there a way to declare an array of IBOutlet UIImageViews?

Just so I don't have so many declarations in my header file.

Krunal
  • 77,632
  • 48
  • 245
  • 261
Marty
  • 5,926
  • 9
  • 53
  • 91

5 Answers5

45

It is possible, it’s called outlet collection. This is the way to define an outlet collection:

@property(retain) IBOutletCollection(UIImageView) NSArray *images;

Now you can stick more than one object into the outlet in the Interface Builder, the array will be created for you when the interface is loaded.

zoul
  • 102,279
  • 44
  • 260
  • 354
  • 7
    It took me quite a long time to work out how to 'stick more than one object into the outlet' in xcode 4. After creating the IBOutletCollection in code I expected to be able to CTRL-Drag from the UIImageView to it. This doesn't work, for some reason. What does work though is to select the 'File's Owner', then open the 'Connections inspector', then drag from the 'Outlet collections' section to each UIImageView in turn. – Ben Clayton Mar 30 '11 at 22:27
  • I couldn't figure out how to implement this - thanks @BenClayton ! – abc123 Mar 20 '13 at 03:10
  • In the developer preview of xcode 5, the issue that @BenClayton mentioned seems to be resolved - CTRL-Drag now does work to bind to the array. Nice answer here! – Dustin Wilhelmi Jun 13 '13 at 01:29
5

Here is more easier way to do it.

Follow these steps to create an array of outlets an connect it with IB Elements:

  • Create an array of IBOutlets
  • Add multiple UIElements (Views) in your Storyboard ViewController interface
  • Select ViewController (In storyboard) and open connection inspector
  • There is option 'Outlet Collections' in connection inspector (You will see an array of outlets there)
  • Connect if with your interface elements

-

class ViewController2: UIViewController {


    @IBOutlet var collection:[UIView]!


    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

enter image description here

Krunal
  • 77,632
  • 48
  • 245
  • 261
4

I'm a little late here but it may be easier to set the tag property of each ImageView in IB, then access them like [some_superview viewWithTag:tag] rather than keep a separate handle to each one.

Rob Lourens
  • 15,081
  • 5
  • 76
  • 91
2

Swift 3 and above:

@IBOutlet var stuckLabels: [UIImageView]
Sam Soffes
  • 14,831
  • 9
  • 76
  • 80
-4

There's not, unfortunately, but you can keep all of the declarations on a single line:

IBOutlet UIImageView *img1, *img2, *img3, *img4;

The other option (probably best, since you have so many of these) would be to create them programatically and store them in an array, then add them to the view from your view controller class, using, for each,

[self.view addSubview:img];

Also, keep in mind that if the elements are static (like background elements), and you don't actually need to access them, you don't need to declare outlets for each; you can just add them to the nib file and forget about them.

Same goes for UIButton instances. If you don't need to change anything about the button, you can access it from the method that it calls, like so:

-(IBAction) buttonPressed:(id)sender {
    UIButton *button = (UIButton *)sender;
    // method guts
    // stuff with button -- access tag, disable, etc
}
Sam Ritchie
  • 10,988
  • 4
  • 42
  • 53
  • I would create them programmatically, but they all need to go in certain places, and I don't want to have to set where to put each one. And I need to change them from hidden to not hidden at certain times, so I need to be able to access them. The single line declaration will make it look neater at least. – Marty Dec 05 '10 at 00:27
  • Yeah, we don't get cocoa bindings on the iPhone, so this is really the best we can do. Did this answer the question? – Sam Ritchie Dec 05 '10 at 00:28