2

I have the error:

Value of type 'UIView' has no member 'tableView'

occur when I attempt to change the background of the tableView in the viewWillAppear method.

I expected the table view would already be initialised from the viewDidLoad method.

Where should I be trying to change the colours for the tableview? Should I also be changing the other background colours in the same place?

class settingsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

  override func viewDidLoad() {
    super.viewDidLoad()

    // Table view setup
    let tableView = UITableView(frame: view.bounds, style: .Plain)
    tableView.delegate = self
    tableView.dataSource = self
    tableView.registerClass(settingsCell.self, forCellReuseIdentifier: NSStringFromClass(settingsCell))
    view.addSubview(tableView)

  }

  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true)

    if nightMode == true {
      view.backgroundColor = UIColor.blackColor()
      view.tableView.backgroundColor = UIColor.blackColor() // Error here..
    }
  }

  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return settings.count
  }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(NSStringFromClass(settingsCell), forIndexPath: indexPath) as! settingsCell

    // Fetch setting
    let cellSetting = settings[indexPath.row]

    // Configure Cell
    cell.textLabel?.text = cellSetting.name

    return cell
  }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • What's the purpose not to use `UITableViewController` or at least an instance variable? – vadian May 10 '16 at 04:32
  • You've got your tableView locally scoped. Put it toward the top outside of viewDidLoad. As it stands, only viewDidLoad "sees" it. See Bhavin's answer for deets – Adrian May 10 '16 at 04:38
  • I'm mostly doing this for practise, at the UIViewController requires me to do more things manually I think. http://stackoverflow.com/questions/14465447/are-there-any-advantages-to-using-a-uitableviewcontroller-over-a-uiviewcontrolle –  May 10 '16 at 04:55
  • Thanks Adrian and Bhavin, I see the tableView only existed inside the viewDidLoad function. For academic interest, was the error because tableView would be dropped from compliler's memory once viewDidLoad is complete? Or because the XCode couldn't see that viewDidLoad was going to run before viewWillAppear and it actually should have worked? –  May 10 '16 at 05:05

3 Answers3

2

You can make it an instance variable of UITableView like

 class settingsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

 var tableView:UITableView!
 override func viewDidLoad() {
      super.viewDidLoad()

      // Table view setup
      tableView = UITableView(frame: view.bounds, style: .Plain)
      tableView.delegate = self
      tableView.dataSource = self
      tableView.registerClass(settingsCell.self, forCellReuseIdentifier: NSStringFromClass(settingsCell))
      view.addSubview(tableView)
}

override func viewWillAppear(animated: Bool) {
     super.viewWillAppear(true)

     if nightMode == true {
         view.backgroundColor = UIColor.blackColor()
         tableView.backgroundColor = UIColor.blackColor()
     }
}  
Bhavin Bhadani
  • 22,224
  • 10
  • 78
  • 108
  • 1) This doesn't define `tableView` "globally" (that has a different meaning). This makes it an instance variable. 2) No need to create the temporary `UITableView` instance when you declare the instance variable. – rmaddy May 10 '16 at 04:31
  • I'm far from fluent in Swift but shouldn't the declaration of the `tableView` instance variable just be `var tableView:UITableView`? Why add the `= UITableView()` part? – rmaddy May 10 '16 at 04:33
  • 1
    The `= UITableView()` creates a new table view. But then you create another in `viewDidLoad`. There's no point in creating that initial table view. – rmaddy May 10 '16 at 04:36
  • @rmaddy without fully declaring the tableView I get error unwrapping a nil value when attempting to access the tableView.background. Therefore, I declared the variable table view, removed the second declaration in viewDidLoad and amended the frame to view.bounds in viewDidLoad. Bhavin suggest your original solution was correct with these changes to viewDidLoad –  May 10 '16 at 07:05
1

This is not the right way of accessing a subview within a view. You can use viewWithTag: to get the subview by tag:

override func viewDidLoad() {
  ...
  tableView.tag = 100
  view.addSubview(tableView)
}

...

override func viewWillAppear(animated: Bool) {
  ...
  if let tableView = view.viewWithTag(100) {
    tableView.backgroundColor = UIColor.blackColor()
  }
}

Alternatively, you make tableView an instance variable if you need to access it in more than just viewWillAppear:

class SettingsViewController: UIViewController ... {
    var tableView: UITableView!
    ...

    override func viewDidLoad() {
      ...
      self.tableView = UITableView(frame: view.bounds, style: .Plain)
      ...
    }

    override func viewWillAppear(animated: Bool) {
      ...
      self.tableView.backgroundColor = UIColor.blackColor()
    }
}
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
  • 2
    Or make `tableView` an instance variable. That would be much better since it is likely the code will need to access the `tableView` in more than just `viewWillAppear`. – rmaddy May 10 '16 at 04:29
1

Declare the tableview in global value, then use the tableview in class, see the below code,

     class ViewController: UIViewController {
            var tableView = UITableView()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        tableview.frame = self.view.bounds
        tableView.delegate = self
        tableView.dataSource = self
        tableView.registerClass(settingsCell.self, forCellReuseIdentifier: NSStringFromClass(settingsCell))
        self.view.addSubview(tableView)
      }

    override func viewWillAppear(animated: Bool) {
            if nightMode == true {
                view.backgroundColor = UIColor.blackColor()
                tableView.backgroundColor = UIColor.blackColor() 
      }
}

hope its helpful

Tyson Vignesh
  • 315
  • 2
  • 14
Iyyappan Ravi
  • 3,205
  • 2
  • 16
  • 30