37

Multiple IBOutlets

I made these (marked with red border) IBOutlets using ctrl + drag

But i don't like to have the exact same line 9 times (DRY)

How do i put these IBOutlets in an Array?

Krunal
  • 77,632
  • 48
  • 245
  • 261
cor
  • 617
  • 2
  • 6
  • 11

5 Answers5

46

you can define a generic outlet collection in Swift like this:

@IBOutlet var collectionOfViews: Array<UIView>? // = [UIView]?

or for e.g. UIButton objects:

@IBOutlet var collectionOfButtons: Array<UIButton>? // = [UIButton]?

you can find your collections under the Outlet Collections group as usually are in the File's Owner:

Outlet Collections

it would look on my console after connecting 5 random buttons:

Connected UIButton instances to Collection

holex
  • 23,961
  • 7
  • 62
  • 76
  • 1
    How do i connect the buttons from the storybord to this array? – cor Jul 17 '14 at 13:51
  • @CorPruijs, you can find your collection under the _Outlet Collections_ group. you can connect the multiple items to the collection as usually you'd do in the case of one outlet. – holex Jul 17 '14 at 13:59
  • I keep getting a "not initialized at super.init call" error, i have tried "@IBOutlet var levelField: Array = Array" and "@IBOutlet var levelField: Array = UIButton" and using a for loop but nothing worked – cor Jul 17 '14 at 14:04
  • @CorPruijs, is that your code, `@IBOutlet var levelField: Array = Array`...? you don't need the right size of the operand, please chuck everything away after the `=` symbol including the `=` too; please see my answer, I have not assigned anything to it, because it is needless. – holex Jul 17 '14 at 14:07
  • That's the first thing i tried off course, but it didn't work.
    Then i tried using the = Array thingy because i needed "= UIButton()" when i did a single button
    – cor Jul 17 '14 at 14:11
  • @CorPruijs, I don't know what else I can do, that works for me well but I'm not seeing your code – therefore I have no idea where the procedure is derailed. – holex Jul 17 '14 at 14:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/57505/discussion-between-corpruijs-and-holex). – cor Jul 17 '14 at 14:15
  • Change `@IBOutlet var collectionOfViews: Array` to `@IBOutlet var collectionOfViews: Array?` to avoid compilation errors. – redent84 Feb 25 '15 at 17:09
  • @redent84, thanks, unfortunately the Swift language is still done after a year, and evolves continuously. – holex Feb 26 '15 at 08:34
  • As of Swift 2 (Xcode 7.1), this does not work as shown above. I added the `IBOutlet` array, and connected the array to the buttons in Interface Builder. But when I try to compile, I get a compiler error "Class `ViewController` has no initializers". The fix suggested is to initialize the array, so: `@IBOutlet var buttonArray: [UIButton] = []` – Jay Imerman Nov 04 '15 at 22:39
  • there is no weak in that example. Does it creating a reference cycle? – coolly Jun 27 '17 at 03:40
  • the collections (a.k.a. `Array`) must be kept alive by a strong reference, there is no `weak` modifier here. – holex Jun 27 '17 at 11:32
  • How i can make work it without array ? @IBOutlet weak var backBtn :UIButton!, refreshBtn :UIButton!, searchBtn:UIButton!, playBtn:UIButton!, cancelDownloadBtn:UIButton! – Jamshed Alam Jan 06 '18 at 02:46
  • @JamshedAlam, _outlet collections_ are always arrays; if you drop the array, it won't be an _outlet collection_ anymore but single _individual outlets_ only. – holex Jan 06 '18 at 12:00
  • Can anyone explain why is the collection outlets not a weak but strong? Is it because it's an array? – Happiehappie Jun 25 '18 at 06:29
  • @Happiehappie, your assumption is correct: you need to keep the array alive. – holex Jul 06 '18 at 16:12
34

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
2

Solution here Swift - IBOutletCollection equivalent

@IBOutlet var objectCollection: [Object]

Community
  • 1
  • 1
hannesr
  • 449
  • 5
  • 12
1

This is for macOS (should be similar for iOS) and I do not find an "Outlet Collections" in my storyboard (looks like they took that option out). So I put all my buttons in an NSStackView and linked the stack from storyboard

@IBOutlet weak var buttons: NSStackView!

and then I looped over them to make changes accordingly

for case let (index, button as NSButton) in buttons.arrangedSubviews.enumerated() {
            if(index + 1 != someButtonIndex) {button.state = .off}
            else {button.state = .on}
        }

you can also use tag instead of index

0

Start with the two view pane where you see both your code and the storyboard. When you make your first IBOutlet connection from the UI to your code, just look carefully at the Connection drop down field and select the option called "Outlet Collection". This will automatically create an array of IBOutlets. Next just look for the little black circle within a circle that is placed in your code where the array is created. Just drag from this circle to all the other UI objects you want to connect to that same collection (not sure if you can mix types). Similarly you can connect all the objects to one Action by dragging from the first black dot created to all the other objects you want to wire up to that action. Also consider EnumerateSequence() to help in working with this Collection. Sweet right?