-3

I have a settings page with a static table where users can select the times they are available to work for each weekday (one section per weekday).

To not have to write the same code for each weekday, I created an array of dictionaries called datepickers that allows me to apply the same logic to override func tableView for multiple days. The array is set up in way so that it can access the date pickers after the class has been initialised.

Coming from a Ruby background where we use dynamic variables and don't explicitly declare types of variables, I'm unsure how to type this var datePickers : [???]. What's the correct way of typing this variable and more generally speaking, is my approach correct to refactor this with an array of dictionaries correct?

import UIKit

class AvailabilityController: UITableViewController {

    @IBOutlet weak var mondaysFromDatePicker: UIDatePicker!
    @IBOutlet weak var mondaysToDatePicker: UIDatePicker!
    @IBOutlet weak var tuesdaysFromDatePicker: UIDatePicker!
    @IBOutlet weak var tuesdaysToDatePicker: UIDatePicker!        

    var datePickers : [???] = {
        get {
            return [
                ["section": 0, "row": 2, "datePicker": self.mondaysFromDatePicker],
                ["section": 0, "row": 4, "datePicker": self.mondaysToDatePicker],
                ["section": 1, "row": 2, "datePicker": self.tuesdaysFromDatePicker],
                ["section": 1, "row": 4, "datePicker": self.tuesdaysToDatePicker]                    
            ]
        }
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

        for datePicker in datePickers {
            if indexPath.section == datePicker["section"]! && indexPath.row == datePicker["row"]! {
                let height:CGFloat = datePicker["datePicker"]!.hidden ? 0.0 : 216.0
                return height
            }
        }

        return super.tableView(tableView, heightForRowAtIndexPath: indexPath)

    }
}
Community
  • 1
  • 1
migu
  • 4,236
  • 5
  • 39
  • 60
  • Thanks, your approach worked: `var datePickers : [[NSObject:AnyObject]] {` It seems I know have to convert `AnyObject` back to `Int` and `UIDatePicker` when calling it. How do I do this: `Int(datePicker["section"]!)` / `datePicker["datePicker"]! as UIDatePicker`? – migu Mar 08 '16 at 20:51
  • http://www.apeth.com/swiftBook/ch04.html#_anyobject – matt Mar 08 '16 at 22:15

1 Answers1

1

An array of dictionaries is of type [[NSObject:AnyObject]].

Please note, however, that you cannot say = and get in the same expression. Either this thing is a computed property or it's a stored property with an initializer; you are trying to make it both at once.

For example, if you want a computed property, you could write:

var datePickers : [[NSObject:AnyObject]]
    {
        return [
            ["section": 0, "row": 2, "datePicker": self.mondaysFromDatePicker],
            ["section": 0, "row": 4, "datePicker": self.mondaysToDatePicker],
            ["section": 1, "row": 2, "datePicker": self.tuesdaysFromDatePicker],
            ["section": 1, "row": 4, "datePicker": self.tuesdaysToDatePicker]
        ]
    }

Your test to see which date picker corresponds to which index path could then read like this:

for datePicker in self.datePickers {
    if let sec = datePicker["section"] as? Int where sec == indexPath.section,
    let row = datePicker["row"] as? Int where row == indexPath.row {
        // do something and return something
    }
}

However, I must add that none of that is how I would actually do any of this. I would make a dictionary of index paths and date pickers:

var datePickers : [NSIndexPath:UIDatePicker] {
    return [
        NSIndexPath(forRow: 2, inSection: 0):self.mondaysFromDatePicker,
        NSIndexPath(forRow: 4, inSection: 0):self.mondaysToDatePicker,
        NSIndexPath(forRow: 2, inSection: 1):self.tuesdaysFromDatePicker,
        NSIndexPath(forRow: 4, inSection: 1):self.tuesdaysToDatePicker,
    ]
}

Why? Because if you do that, then getting the correct date picker for this index path is trivially simple:

if let dp = self.datePickers[indexPath] {
    // ...
}
matt
  • 515,959
  • 87
  • 875
  • 1,141