Exceen Exceen - 1 year ago 59
Swift Question

Navigation like in the mail app with segues and dynamic cells in a table view?

I'm currently developing my first iOS app for a college. When you start the app, there is a grouped table view which should represent a menu. This works fine so far, but I'm unable to connect the segues properly. As far as I know I should connect the cell itself with the navigation controller it should lead to. Although every cell should lead to another navigation controller. It's a menu, so that point should be clear. Unfortunately I'm unable to connect a single cell with multiple navigation controllers and when I add multiple prototype cells, I have the problem that every cell should have it's own identifier.

The first screen you see in my app looks basically like the mail app. There are two groups and each cell leads to another navigation controller.

I managed to implement the navigation in some weird way, but get a lot of bugs like "nested push results in corrupted nav bar".

I'm absolutely frustrated right now, I spent a lot of hours on this single problem already and I'm unable to find any solution.

one of the biggest problems currently is that if I navigate to a point and then head back the the view before, the grouped view is first displayed too close to the top and when the animation is complete the whole view jumps back down where it belongs.

this is how it should look like (and looks like when it jumps back): https://dl.dropboxusercontent.com/u/34140308/uploads/2016-04-25%2010.28.48.png

this is how it looks like during the animation: https://dl.dropboxusercontent.com/u/34140308/uploads/2016-04-25%2010.28.48%202.png

edit2: I connected the view controller itself (not the cells) with the respective view controller. Then I call the segues programmatically like this:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
if indexPath.section == 0 {
if indexPath.row == 0 {
self.performSegueWithIdentifier("showSpeiseplan", sender: self)
} else if indexPath.row == 1 {
self.performSegueWithIdentifier("showStudiersaal", sender: self)
} else if indexPath.row == 2 {
self.performSegueWithIdentifier("showErzieher", sender: self)
} else if indexPath.row == 3 {
self.performSegueWithIdentifier("showHausordnung", sender: self)
} else if indexPath.row == 4 {
self.performSegueWithIdentifier("showNews", sender: self)
} else if indexPath.section == 1 {
if indexPath.row == 0 {
self.performSegueWithIdentifier("showZugewieseneStunden", sender: self)

The other major problem right now is that if you press a single cell multiple times before it's loaded, the view gets opened multiple times as well.

Answer Source

The way I usually do segue's from a tableView is by connecting the segue from the viewController rather than the tableviewCells. This way you can call performSegueWithIdentifier in didSelectRowAtIndexPath.


func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    tableView.deselectRowAtIndexPath(indexPath, animated: true)
    tableView.userInteractionEnabled = false

    switch indexPath.section {
    case 0:
        switch indexPath.row {
        case 0: performSegueWithIdentifier("showSpeiseplan", sender: self)
        case 1: performSegueWithIdentifier("showStudiersaal", sender self)
        case 2: performSegueWithIdentifier("showErzieher", sender self)
        case 3: performSegueWithIdentifier("showHausordnung", sender self)
        case 4: performSegueWithIdentifier("showNews", sender self)
        default: tableView.userInteractionEnabled = true
    case 1:
        switch indexPath.row {
        case 0: performSegueWithIdentifier("showZugewieseneStunden", sender: self)
        default: tableView.userInteractionEnabled = true
    default: tableView.userInteractionEnabled = true

and in viewWillDisappear:

 override func viewDidDisappear(animated: Bool) {
    tableView.userInteractionEnabled = true

If your cells are editable or dynamic (they change indexPath) then either use cell.tag in cellForRowAtIndexPath to distinguish them, or add a property to you custom cell class (or make one if you haven't) and add a property that you can use to identify the correct segue.

Edit: To fix the tableView Offset jump on animation, create a variable tableViewContentOffset above viewDidLoad, and then in viewDidLoad add:

 tableViewContentOffset = tableView.contentOffset

and in viewWillAppear restore it if it has changed.

if tableView.contentOffset != tableViewContentOffset {
    tableView.contentOffset = tableViewContentOffset

also, maybe just see what happens when you put this in viewWillAppear:

tableView.contentOffset = CGPointZero
tableView.contentInset = UIEdgeInsetsZero
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download