Iso1234 Iso1234 - 1 year ago 50
Swift Question

Declaring a multi-type array

I would like to have my function return an array in which the first element is a String and the second is a UIImageView object. E.g.

["An example string", UIImageView()]

How do I tell the function that this will be returned in the section that follows the ->

So basically I want a function like this:

func DoSomething(num:Int) -> Array[String, UIImageView()] {

// Each of the following objects in the Array are UIImageView objects
Let imageViewObjects = [image1, image2, image3]

return [String(num), imageViewObjects[num]]

But the part I know I am getting wrong is the

Array[String, UIImageView]

P.S. I need to declare this because if I use [AnyObject] it will raise an error later on in the code basically saying that it cant manipulate an object of type AnyObject

Answer Source

The easiest thing to do is use a tuple, declared like this:

[(String, UIImageView)]

I would use it like this (your code with corrections):

import UIKit

// Returning an Optional to pass back that num may be out of range
func DoSomething(num:Int) -> [(String, UIImageView)]? {
  let image1 = UIImageView()
  let image2 = UIImageView()
  let image3 = UIImageView()
  let imageViewObjects = [image1, image2, image3]
  // Need to check that num is a valid index
  guard num < imageViewObjects.count else { return nil }
  // return the tuple if num is valid
  return [(String(num), imageViewObjects[num])]

Note that I declared an Array as [] rather than Array[]. Both [Int] and Array<Int> are the same thing. You don't need to use both at once.

You can also use protocols to create a common protocol, add it to the classes in an extension, and then use the protocol in the declaration:

protocol Foo {}
extension String : Foo {}
extension UIImageView: Foo {}
var myArray:[Foo] ...

A tuple is usually the better choice unless you are using custom structs and classes.