I'm working with revealViewController, and inside this revealViewController I wanted to create a UITableView with custom cells according to this tutorial: https://www.youtube.com/watch?v=EVJiprvRLoo
and here is my code:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let vcName = identities[indexPath.row]
let viewController = storyboard?.instantiateViewControllerWithIdentifier(vcName)
self.navigationController?.pushViewController(viewController!, animated: true)
}
I'm using a storyboard, but I didn't get any issues, but it's not working.
I also tried to make a push segue to that view controller, but then my navigationViewController disappears, and I think it's would be easier by using code.
Sorry if my question is not accurate, but hope you can understand it.
Many Thanks.
Your self.navigationController? is nil. You should do something like this:
let vcName = identities[indexPath.row]
let viewController = storyboard?.instantiateViewControllerWithIdentifier(vcName)
let navVC = UINavigationController(rootViewController:viewController)
and then set front view controller by method of SWRevealViewController:
- (void)pushFrontViewController:(UIViewController *)frontViewController animated:(BOOL)animated;
self.revealViewController.pushFrontViewController(navVC, animated:true)
You have to push to the RevealController Not to the ViewController
Related
I have a viewController where I have a tableview and inside every cell I have a collectionView.
I want to go to another view (where I will have a back button) so I tried to use my code which is working for the other views:
let vc = self.storyboard?.instantiateViewController(withIdentifier: "detail") as! DetailView
vc.name = beachesNames[indexPath.row]
vc.imagak = imagesNames[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
But because this code is inside the TableViewCell I have an error that says:
Value of type 'HomeViewCell' has no member 'storyboard'
Is there any alternative parameter that I can use or something else it could do my task?
Thanks in advance.
- swift 3
let detailOrderVC = UIViewController()
self.viewController()?.navigationController?.pushViewController(detailOrderVC, animated: true)
- swift 4
in swift 4, you need to pass the viewcontroller to the cell like below
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! CustomTableViewCell
// some your logic
cell.viewController = self // CustomTableViewCell needs to have viewController member variable
return cell
}
let detailOrderVC = UIViewController()
self.viewController?.navigationController?.pushViewController(detailOrderVC, animated: true)
If you are pushing to a view class that requires layout you must call layout at the same time.
ex.
let layout = UICollectionViewFlowLayout()
let nextViewclass = NextClass(collectionViewLayout: layout)
self.navigationController?.pushViewController(nextViewclass, animated: true)
If you have a collection view inside of every cell, then I would recommend having each cell hold a container view. The view controller associated with the container view will have a storyboard.
The code for the push would look a bit ugly:
self.parent?.navigationController?.pushViewController(vc, animated: true)
The parent?. goes from the contained view controller to the parent view controller.
What you're missing is instantiating the storyboard:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
storyboard.instantiateViewControllerWithIdentifier("myNavigationController") as! UINavigationController
But as this stackoverflow answer says, this generally isn't a good MVC design.
You might want to look into delegate patterns or using NotificationCenter. Both these ways essentially trigger a call to the parent view which will then handle the corresponding action.
i have a tableview and i want to go to another vc when one of rows tapped. my didSelectRowAtIndexPath function is as below. print command works and shows the right clicked row. but when i use self.navigationController?.pushViewController it does not go to vc with playVideo storyBoardId. after changing it to presentViewController it works. what's wrong about my code that push doesn't work?
thanks
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("clicked " + String(indexPath.row) )
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("playVideo") as! PlayVideoViewController
vc.id = self.video[indexPath.row].id
// Present View as Modal
//presentViewController(vc as UIViewController, animated: true, completion: nil)
// Push View
//self.navigationController?.pushViewController(vc, animated: true)
}
Its because the view controller you are currently in may not have a navigation controller.
You cannot push a view controller without having a UINavigationController.
If your requirement is to push a view controller, then perform the following steps.
Embed a navigation controller for the current view controller.(Open storyboard -> Choose your view controller -> Choose "Editor" -> "Embed in" -> UINavigationController)
Now your code
self.navigationController?.pushViewController(vc, animated: true)
will be working fine.
Make sure that your ViewController is indeed built on a NavigationController. Try forcing the line:
self.navigationController!.pushViewController
if it crashes, you know there is not nav set up. Or you could just check in your storyboard but this is a quick way to tell.
I dont know why are you doing it like this. I think its unnecessarily complicated.
This should by your function didSelectRowAtIndexPath:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("playVideo", sender: tableView)
}
Then you can specify as much segues as you want in this function:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "playVideo") {
let indexPath:NSIndexPath = tableView.indexPathForSelectedRow!
let PlayVideoViewController = segue.destinationViewController as! PlayVideoViewController
//you can pass parameters like project id
detailVC.projectID = ids[indexPath.row]
}
}
Your segue has to be named like this in interface builder:
I have a TableViewController in a TabBar.
When I select one cell of my tableView, I want start a new controller with pushViewController(MyNewController).
This is my code :
In my TableView :
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myController = (storyboard.instantiateViewControllerWithIdentifier("MyViewController") as? MyViewController)!
myController.parameter = self.tableau[indexPath.row]
UINavigationController().pushViewController(myController, animated: true)
}
In my TabBar :
func viewDidLoad() {
super.viewDidLoad()
var controllerArray: [UIViewController] = []
let controller: UIViewController = ClubPreviewListViewController()
controller.title = "TEST"
controllerArray.append(controller)
self.view.addSubview(pageMenu!.view)
}
(I use CAPSPageMenu for customize my TabBar, but it's not the problem, I have the same problem without)
In my controller :
deinit {
print ("TEST")
}
When I select a cell, the log write "TEST" everytime I select but don't change the view.
I think it's my navigationController the problem, but I don't know how to fix it.
Before I implement the TabBar, I use my TableView alone, and the push did works.
Sorry for my english ! Thanks for your help.
EDIT:
I change my pushViewController :
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myController = (storyboard.instantiateViewControllerWithIdentifier("MyViewController") as? MyViewController)!
myController.parameter = self.tableau[indexPath.row]
//UINavigationController().pushViewController(myController, animated: true)
self.navigationController?.pushViewController(myController, animated: true)
}
Same reaction.
My NavigationController isn't directly link with my TabBar. I need to create an other one ? I don't really understand how NavigationController works !
This is my configuration
EDIT2:
If I use the navigationController of my TabBar and not of my TableView, the view change !
self.saveTabBarNavigationController.pushViewController(myController, animated: true)
You are creating an instance of a navigation controller on the line
UINavigationController().pushViewController(myController, animated: true)
Once this method finishes executing, the navigation controller and its view controllers will be deallocated because nothing retains your navigation controller. Causing 'TEST' to be printed in your deinit() function.
You should be obtaining the navigation controller that owns your current tab bar controller and pushing onto the stack using that. Without knowing the structure of your application it is difficult to know where your navigation controller is (if it exists).
Check your storyboard, but essentially try:
self.navigationController.pushViewController(myController, animated: true)
Try this it will work only if you have a navigation embedded tabbar controller
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myController = (storyboard.instantiateViewControllerWithIdentifier("MyViewController") as? MyViewController)!
myController.parameter = self.tableau[indexPath.row]
navigationController.pushViewController(myController, animated: true)
}
This question already has answers here:
How to make a push segue when a UITableViewCell is selected
(10 answers)
Closed 6 years ago.
I have one table view controller and by clicking the cell i am redirecting the user to detail view controller.But when i perform segue " present view controller" its working fine.But what i need is?
I need to perform push segue by clicking the table view cell.How to do that?
Here is my code:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc: BusinessDetailViewController = storyboard.instantiateViewControllerWithIdentifier("BusinessDetailViewController") as! BusinessDetailViewController
vc.BusinessData = arrDict[indexPath.row]
self.presentViewController(vc, animated: true, completion: nil)
}
I have tried this below line :
self.navigationController?.pushViewController(vc, animated: true)
But it doesn't work.Any Solution Please !!
First of all your UITableViewController must have a UINavigationController
To do it rapidly embedded it to your table from the xCode menu
:
Then , you must create the segue, ctrl-drag from the UITableViewController to the destination viewController:
Then select the segue and give it an identifier in the property inspector:
Now you are able to perform this segue in code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
performSegueWithIdentifier("mySegue", sender: cell)
}
If you are not using UINavigationController than add a segue in storyboard from table cell to destination viewController and give a identifier to segue.
then on cell click call
- performSegueWithIdentifier:sender:
and implement
- prepareForSegue:sender:
Without a navigation controller it's not possible to push a controller. Your self.navigationController property is nil (you can check it)
How to solve it?
A :You need to embed your view controller in navigation controller either via code or via storyboard
try this code, its working for me,
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("PlayViewController") as! PlayViewController
self.navigationController?.pushViewController(controller, animated: true)
}
and set the storyboard Id, example given below,
hope its helpful
i got an app without storyboards, all UI creation is made in code and I got a splitView which I would make it usable on iPhone, because as the app as been first designed for iPad only, so that when you select a row in the list in the Master view it does nothing on iPhone but is working fine on iPad.
So my question is can I create and perform the segue that allows to show the Detail View on the didSelectRowAtIndexPath method ?
Here's what i've done so far :
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let segue = UIStoryboardSegue(identifier: "test", source: self, destination: detailViewController!)
performSegueWithIdentifier("test", sender: self)
}
but when running and selecting a row the app was crashing telling it needed a performhandler so i added this :
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let segue = UIStoryboardSegue(identifier: "test", source: self, destination: detailViewController!, performHandler: { () -> Void in
let object = self.fetchedResultsController.objectAtIndexPath(indexPath)
let controller = self.detailViewController!
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
})
performSegueWithIdentifier("test", sender: self)
}
and now when selecting a row xcode says that there is no segue with such identifier "test".
I also tried to call it by segue.perform() and add the performHandler content into the prepareForSegueMethod :
if segue.identifier == "test" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let object = self.fetchedResultsController.objectAtIndexPath(indexPath)
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
and it does just nothing, doesn't crash, just highlight the row i selected and that's all
Can you guys help me ?
EDIT : As Oleg Gordiichuk said, it's not possible to do what I want to do without Storyboards, so thanks for his help :)
Segue it is component of the storyboard interaction it is possible to understand from name of the class UIStoryboardSegue. It is bad idea to create segues programmatically. If i am not making mistake storyboard creates them for you.
For solving of you're issue try to use some common ways like simply present ViewController.
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("id") as! MyController
self.presentViewController(vc, animated: true, completion: nil)
As i understand from our conversation in comments. You would like to create navigation for tableview to details view using segues without storyboard. For now it is impossible to do this without storyboard.
For future learning try to investigate this information.
One way is to use the didSelectRow method for tableView
Swift 3.x
// MARK: - Navigation & Pass Data
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Selected Row \(indexPath.row)")
let nextVC = YourNextViewController()
nextVC.YourLabel.text = "Passed Text"
nextVC.YourLabel.text = YourArray[indexPath.row]
// Push to next view
navigationController?.pushViewController(nextVC, animated: true)
}