0

I am trying to overcome the limitation explained here about not being able to directly connect IB elements to outlets with protocol types.

The workaround mentioned is not ideal because what I need an Outlet Collection and connecting a new element means redoing this again and again and that defeats the purpose of this part of my project.

So I figured I would create an intermediate Controller whose sole purpose was to readily translate a an AnyObject outlet collection to the array typed with my Protocol.

I come to discover that the array casting you see below throws the error: "Type 'FormField' does not conform to protocol 'AnyObject'"

However, the simple per-item loop commented out actually works.

I would like to understand why the former fails and if there is a way to actually avoid the per-item loop.

class FormViewController: UIViewController, Form {

    @IBOutlet var fieldCollection: [AnyObject]!

    var formFields: [FormField]!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.formFields = self.fieldCollection as! [FormField]!
        /*
            self.formFields = [FormField]()
            for field in self.fieldCollection {
            self.formFields.append(field as! FormField)
        }*/
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
Community
  • 1
  • 1
RobertoCuba
  • 881
  • 9
  • 25

1 Answers1

0

You didn't show how the FormField protocol is defined but I'm guessing it doesn't have the AnyObject class as a constraint.

for example: protocol FormField:class, AnyObject {}

If it did, the type cast would work.

you could then declare it as:

class FormViewController: UIViewController, Form {

    @IBOutlet var fieldCollection: [AnyObject]!
    var formFields: [FormField] { return fieldCollection as! [FormField] }

and I believe you could event do this (in Swift 2.1):

    @IBOutlet var fieldCollection: [FormField]!
Alain T.
  • 40,517
  • 4
  • 31
  • 51
  • I totally forgot to mention that I indeed attempted to have FormField conform to AnyObject (just like in your example) but it also gave an EXC_BAD_INSTRUCTION error with log: "fatal error: array cannot be bridged from Objective-C." I think I completely forgot about that approach because I also don't even know what it would "mean" for a Protocol to conform to AnyObject so I didn't pursue it further. That was just a blind attempt on my end going just by the error message. Have you tried your own example? Because if it works for you then I am just missing something really small – RobertoCuba Jan 21 '16 at 05:34
  • For UI components you need to make it conform to NSObject. I didn't realize that your FormFields were UI controls (my bad). – Alain T. Jan 21 '16 at 05:54
  • By the way I had tried my example but used mock classes in the playground to go faster. That's why I made that oversight with NSObject. – Alain T. Jan 21 '16 at 13:24