I have a tableView with some results of a search. I have connected the first and the second view with the "storyboard Segue" from the cell to the second view.
This is the code written in the first ViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = self.tableProva.indexPathForSelectedRow?.row
let vc = segue.destination as! DettaglioNewViewController
vc.titleLibro = posts[indexPath!].name
vc.authorLibro = posts[indexPath!].author
vc.ISBNLibro = posts[indexPath!].ISBN
}
In other project it works perfectly, but in this project it doesn't work, to show the second viewController I have to tap and swipe to the right or left.
It seems that the problem is graphic.
If I try to click on the cell does not become gray. turns gray if I hold down long on it
Has this happened to anyone else?
Can anyone help me?
You should use the 'didSelectRowAtIndexPath' method in order to segue to a different view for a specific cell. Use.....
var storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle(forClass: self.dynamicType))
vc = storyboard.instantiateViewControllerWithIdentifier("LoginVC") as DettaglioNewViewController
vc.loadView()
..... To segue needed information.
* Information Example *
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
myFavIndex = indexPath.row
let storyBoard = UIStoryboard(name: "Main", bundle:nil)
let view = storyBoard.instantiateViewControllerWithIdentifier("LoginVC") as! DettaglioNewViewController
view.imageURL = self.imageArray[mySelectedIndex]
view.titleString = self.titleArray[mySelectedIndex]
self.presentViewController(view, animated: true, completion: nil)
}
In the above example I'm using the new View Controllers image and title as view.imageURL and view.titleString to populate that views elements from my selected Cells Information via [mySelectedIndex]. You should be able to do this with an Int, UIImage, String, e.g.
You don't need to initialize your controller from the code. Just create a custom segue and call 'performSegue' method in 'didSelect' method of table delegate.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
self.performSegueWithIdentifier("yourIdentifierInStoryboardForCustomSegue", sender: nil)
}
Related
I am working at my first application in Swift 3. I am using tableView (by "extension MainController: UITableViewDataSource"). And from this tableView, by storyboard I have two segues. One for editing (by clicking on accessory icon) and the second one for more detail screen (by clicking on a table row). I am not calling this segues by code, but by storyboard.
And my problem is that there is sometimes huge lag. Like after clicking on a row, the next screen is showing after 30 seconds. But now always. Sometimes its working immediately. Interesting thing is that when I touch row 1, and nothing happens, next I am clicking row 2 and then row 1 is appearing.
I am also using delegates, this is the code for preparing segues:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// 1
if segue.identifier == "AddSensor" {
// 2
let navigationController = segue.destination
as! UINavigationController
// 3
let controller = navigationController.topViewController
as! AddController
// 4
controller.delegate = self
}
else if segue.identifier == "EditSensor" {
let navigationController = segue.destination
as! UINavigationController
let controller = navigationController.topViewController
as! AddController
controller.delegate = self
if let indexPath = tableView.indexPath(
for: sender as! UITableViewCell) {
controller.sensorToEdit = sensors[indexPath.row]
}
}
else if segue.identifier == "DetailSeq" {
let navigationController = segue.destination
as! UINavigationController
let controller = navigationController.topViewController
as! DetailController
controller.delegate = self
if let indexPath = tableView.indexPath(
for: sender as! UITableViewCell) {
controller.sensorRecieved = sensors[indexPath.row]
}
}
}
I was reading that it was common bug in iOS8 and could be resolved by adding
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
DispatchQueue.main.async {
self.performSegue(withIdentifier: "DetailSeq",sender: self)
}
}
But it didn't worked for me. I don't know what should I do next to resolve this problem. Can anyone guide me?
According to this SO question, you may be able to fix your bug if you present your view controller in code rather than with the segue in the storyboard. Something like this, where your destination is the VC that you want to go to.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath:
NSIndexPath) {
DispatchQueue.main.async {
self.presentViewController(destination, animated: true) { () -> Void
in
}
}
}
You have to use like this :
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
DispatchQueue.main.async {
self.performSegue(withIdentifier: "DetailSeq",sender: self)
}
}
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:
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)
}
In my project, I have a few View Controllers and I use UINavigationController.
When I make a seque from UIViewController to UITableViewController I have "back" button added automatically, but when I make seque from UITableViewController to UIContentViewController tapped a cell, I don't have a "back" button in UIContentViewController.
Plan of my app is here
The segue in UITableViewController looks like that:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let CV = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController
let tnumber = tableView.indexPathForSelectedRow?.item
CV.titleContent = daneOWpisach?[tnumber!]["title"]
CV.webContent = daneOWpisach?[tnumber!]["description"]
CV.category = category
self.presentViewController(CV, animated: true, completion: nil)
}
What should I do, if I would like to have a back button in UIContentViewController added automatically?
In your code you are presenting the view controller on cell selection..! Back button will show only if you perform push not on presenting the view.
In the above diagram what I have seen is you already make the segue from UITableViewController to UIContentViewController. select the segue and go to attribute inspector give the identifier for the segue.
On the cell selection perform the segue action with the identifier you specified
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("Your Segue name", sender: sender)
}
If you want to pass data to destination view controller, do it like below..
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "Your Segue name" {
let CV = segue.destinationViewController as! ContentViewController
let tnumber = tableView.indexPathForSelectedRow?.item
CV.titleContent = daneOWpisach?[tnumber!]["title"]
CV.webContent = daneOWpisach?[tnumber!]["description"]
CV.category = category
}
}
Hope this helps you