1

I have a split view controller. Everything loads properly, except when you're in portrait and you rotate to landscape, the cell current gets de-selected.

I found the problem. The table was reloading data every time the viewWillAppear function was called, and viewWillAppear is called every time the device is rotated.

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    table.reloadData()
}

Now there's a new issue. I need to update the TableView whenever I add an item from a modal view. The modal view is another view controller. I tried:

MasterViewContoller().table.reloadData()

That raised a bunch of flags and I'm pretty sure that's not the right way to do it. So how can I reload the table from another view?

==============

For those think that the ViewWillAppear is not called on rotation, try this and see:

class MasterViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
println("rotated")
}

}
class DetailedViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

}
Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
JoeBayLD
  • 939
  • 2
  • 10
  • 25
  • `viewWillAppear` is not called on rotation. The premise of this question is bad. Spend some more time debugging. If you can confirm with the debugger that `viewWillAppear` is being called on each rotation, then something else is calling it. – nhgrif Nov 08 '14 at 02:20
  • @nhgrif The premise of your answer is bad. I don't appreciate the -1 as you are INCORRECT. Take a look at my edit code. – JoeBayLD Nov 08 '14 at 02:45
  • It's not an answer. And I'm not incorrect. If `viewWillAppear` is being called, it's because something else is calling it. I just checked in a fresh project completely from scratch. `viewWillAppear` is not called normally by rotation--something else is calling it. – nhgrif Nov 08 '14 at 02:48
  • I'm not making fast assumptions. `viewWillAppear` isn't called by default on rotation. Rather than getting all uppity when someone explains that your problems is elsewhere, why don't you instead include all of the details from the beginning? The only assumption I've made is that iOS is behaving normally. – nhgrif Nov 08 '14 at 02:50
  • @nhgrif Well that is incorrect, Because I just tested it as well. On the iPhone 6 Plus, it's going from a portrait detailed view controller to a landscape split view, therefore making the master view appear and calling the "viewWillAppear". I did include all the details in the beginning. I said it was a SplitView Controller. And a SplitView Controller has this behavior. – JoeBayLD Nov 08 '14 at 02:51
  • It's not incorrect. My assumption is correct because that *is* the **normal** behavior. It's not the case here because a) master-detail view controller which could be made more clear in the question and more specifically b) iPhone 6 Plus (this wouldn't be the case on any other size iPhone), and that's a fact you don't even mention at all in your question. So stop chastising me for your failure to include relevant details in your question. – nhgrif Nov 08 '14 at 02:53
  • @nhgrif read the first sentence of my post. – JoeBayLD Nov 08 '14 at 02:55
  • 1
    @JoeBayLD the problem is that the whole `viewWillAppear` issue is a red herring. It has absolutely nothing to do with the question you asked. You would be better off removing everything about viewWillAppear getting called and only talk about the question you are asking. – Daniel T. Nov 08 '14 at 02:56
  • I did miss that, but the fact remains that this still isn't the behavior on any iPhone except the 6 Plus, and no where in your question do you mention this problem being specific to the 6 Plus versus other phone sizes. – nhgrif Nov 08 '14 at 02:56

1 Answers1

0

The standard solution to your problem is to use a delegate.

protocol ModalViewControllerDelegate {
    func updateInModalViewController(sender: ModalViewController)
}

class MainViewController: UIViewController, ModalViewControllerDelegate {
    func prepareForSegue(_ segue: UIStoryboardSegue, sender sender: AnyObject?) {
        if let controller = segue.destinationViewController as? ModalViewController {
            controller.delegate = self
        }
    }
    // the rest should be pretty obvious
}
Daniel T.
  • 32,821
  • 6
  • 50
  • 72
  • This sorta helps. Still a bit confused. Where would I apply the table.reloadData() function? – JoeBayLD Nov 08 '14 at 03:01
  • Also, I'm not sure that fits my problem. It appears that your destination is the ModalViewController. However, in my case, I'm sending from the ModalViewController back to a standard View. I tried creating that protocol and adding it, and I got: Type does not conform to protocol ModalViewControllerDelegate – JoeBayLD Nov 08 '14 at 03:08
  • Right, so do the obvious thing to make the MainViewController conform to the protocol. What do you think you should put in the updateInModalViweController function? I'm trying to help you help yourself. – Daniel T. Nov 08 '14 at 03:26
  • And check out this question: http://stackoverflow.com/questions/6168919/how-do-i-set-up-a-simple-delegate-to-communicate-between-two-view-controllers – Daniel T. Nov 08 '14 at 03:28
  • I tried: protocol ModalViewControllerDelegate { func updateInModalViewController(sender: TabbViewController){ sender.table.reloadData() } } – JoeBayLD Nov 08 '14 at 03:30
  • Unfortunately there aren't any swift answers. I'm not familiar with Obj-C – JoeBayLD Nov 08 '14 at 03:32
  • Still confused. Would the prepareForSegue be in my Modal controller? I got the protocol in my main controller. What do I need to call from the Modal view to run updateInModalViewController? – JoeBayLD Nov 08 '14 at 03:52
  • The thing is, your question has nothing to do with Swift. It has to do with the general notion of how objects communicate with each other. Your main view controller needs to know when the important thing has happened so it can do its job. Your modal view controller knows when the important thing has happened. So main has to tell modal "let me know when the important thing has happened" and modal then needs to tell main "the important thing has happened" after the important thing happened. Main tells modal by assigning itself to the `delegate` property, modal tells main by calling `update`... – Daniel T. Nov 08 '14 at 03:53
  • I see. I'm still learning (thus my membership on this site). I think I have everything setup in the way you stated, only thing that isn't clicking is the controller.delegate = self. So that is pulling from the Modal view? I get an error that the Modal view doesn't have a member "delegate".. Thanks for the help so far. – JoeBayLD Nov 08 '14 at 04:03
  • All set. I found that I had to make a delegate variable. Thanks for the help. – JoeBayLD Nov 08 '14 at 04:21
  • No problem, just accept the answer. Also, understand that this is a general solution, good for all kinds of situations, not just view controllers, and not just in Swift. You will be using this pattern constantly, every time you program, no matter what language you use. – Daniel T. Nov 08 '14 at 04:28