Dan Beaulieu
Dan Beaulieu

Reputation: 19954

How do I segue from a programmatically created UITableView?

I'm working on an app that has a menu that slides in from the left. The menu built programatically using a UITableView and an NSObject. I've been able to populate the slide out menu with items but I don't know how to create a segue with an Identifier without using Interface Builder.

Here's what I am tying to do in my tableView:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cellForRow = tableView.cellForRowAtIndexPath(indexPath)
    let cellLabel = cellForRow?.textLabel?.text

    delegate?.sideBarControlDidSelectRow(indexPath, cellName: cellLabel!)  

    if (cellLabel == "Item1") {
        self.performSegueWithIdentifier("item1Settings", sender: nil)
    } else {
        self.performSegueWithIdentifier("item2Settings", sender: nil)
    }

}

( gist: SideBarTableViewController)

When I click a cell in the menu I get the following error:

2015-06-11 18:35:28.720 SideBarApp[2862:1111870] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver () has no segue with identifier 'item1Settings'' * First throw call stack: (0x1822882d8 0x193aac0e4 0x186fe4c00 0x10000b030 0x10000b108 0x186df1474 0x186eab790 0x186d4c240 0x186cbc6ec 0x1822402a4 0x18223d230 0x18223d610 0x1821692d4 0x18b97f6fc 0x186d2efac 0x1000147cc 0x19412aa08) libc++abi.dylib: terminating with uncaught exception of type NSException

After searching stack I found a few solutions in Objective-C but nothing for Swift with this scenario.

How do I segue from a programmatically created UITableView?


This is where I assemble the UITableView programmatically:

SideBar.swift View Entire File

func setupSideBar(){

    sideBarContainerView.frame = CGRectMake(-barWidth - 1, originView.frame.origin.y, barWidth, originView.frame.size.height)
    sideBarContainerView.backgroundColor = UIColor.clearColor()
    sideBarContainerView.clipsToBounds = false

    originView.addSubview(sideBarContainerView)

    let blurView:UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
    blurView.frame = sideBarContainerView.bounds
    sideBarContainerView.addSubview(blurView)


    sideBarTableViewController.delegate = self
    sideBarTableViewController.tableView.frame = sideBarContainerView.bounds
    sideBarTableViewController.tableView.clipsToBounds = false
    sideBarTableViewController.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
    sideBarTableViewController.tableView.backgroundColor = UIColor.clearColor()
    sideBarTableViewController.tableView.scrollsToTop  = false
    sideBarTableViewController.tableView.contentInset = UIEdgeInsetsMake(sideBarTableViewTopInset, 0, 0, 0)

    sideBarTableViewController.tableView.reloadData()
   sideBarContainerView.addSubview(sideBarTableViewController.tableView)

    }

Here is where I call it:

ViewController.swift (initial view)

override func viewDidLoad() {
    super.viewDidLoad()
    imageView.image = UIImage(named: "image2")
    sideBar = SideBar(sourceView: self.view, menuItems: ["first item", "second item", "funny item", "another item"])
    sideBar.delegate = self

    }

Upvotes: 0

Views: 1878

Answers (3)

Dan Beaulieu
Dan Beaulieu

Reputation: 19954

I figured it out... I needed to perform the segue from my viewController not my SideBarTableViewController:

class ViewController: UIViewController, SideBarDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        sideBar = SideBar(sourceView: self.view, menuItems: ["Item1", "item2"])
        sideBar.delegate = self
    }

    func sideBarDidSelectButtonAtIndex(index: Int) {

        if (index == 0) {
            self.performSegueWithIdentifier("item1", sender: self)
        } else {
            self.performSegueWithIdentifier("item2", sender: self)
        }

    }

Upvotes: 0

Jonah
Jonah

Reputation: 42

What it looks like you're trying to do is open a settings page when you select a cell. To do this, you need to define a new UIViewController to hold the settings page code. Also create a UIStoryboardSegue to connect the current UIViewController and your new SettingsViewController.

Then, using override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) you can get the SettingsViewController just before it is opened, set whatever properties you need to on it, and let it finish launching with this new data at its disposal. Some data you might pass along could contain information telling the SettingsViewController which cell was selected, and what interface it should therefor offer to the user.

If that isn't working out for you, you can instantiate the SettingsViewController, set properties on it, and when you're ready, call currentController.presentViewController(settingsController, animated: blah, completion: blah)

Upvotes: 2

Icaro
Icaro

Reputation: 14845

Do you have an segue with the identifier item1Settings? To check select your segue and check in the identifier is set to item1Settings. It seems that swift is not finding this name setup in your storyboard.

enter image description here

Upvotes: 1

Related Questions