So I have a UITableView populated with questions. The cells of this table have a segue relationship to another view that contains the answer to the question. This segue has an identifier 'showAnswer'. Now I want to implement search functionality on the question table and I want each cell in the results to also segue to the answers view.
So in the question table controller have the code to add the search bar and its controller (this in Swift by the way but the logic is still the same):
let resultsController = SearchResultsController()
resultsController.questions = questions
searchController = UISearchController(searchResultsController: resultsController)
let searchBar = searchController.searchBar
searchBar.placeholder = "Enter a search term..."
searchBar.sizeToFit()
questionTable.tableHeaderView = searchBar
searchController.searchResultsUpdater = resultsController
Now in the SearchResultsController once a row has been selected I want to segue to the answers view. Here is what I got:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("showAnswer", sender: self)
}
Now this crashes and I get the error that 'reciever SearchResultsController has no segue with identifier 'showAnswer'. This makes sense, but how do I fix this? Since I added the SearchResultsController programmatically there is nothing for me to ctrl+drag to on the storyboard to create a segue relationship between the SearchResultsController and the AnswersController. So what do I do?
You need to connect the segue from the holding view controller to the answers view and perform the segue from the holding view controller instead of from the search controller.
you should also send the appropriate data in the sender argument of the segue so the view controller you are navigating to can change according to the question that was chosen
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
YourViewController.performSegueWithIdentifier("showAnswer", sender: questions[indexPath.row])
}
Related
In a table view controller, I'm trying to get the index of the row that is selected before I segue (will pass this info in prepare for segue eventually). I have implemented this function:
var selectedQuestionCell: IndexPath?
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedQuestionCell = indexPath
}
This was working great for me initially. I was able to snag the index of the selected row in my table. However, I want to perform a segue when a row is tapped which will transfer to another View. I connected a segue to my cell (dynamic prototypes). After connecting a segue, my override function no longer executes! I'm really new to Table View Controllers, so I'm not sure if there's anyway I can manually execute this.
To summarize: my problem is after connecting a segue to my cells, the override function to get their index is no longer called. How can I fix this?
Try these thing
Create a new segue from your tableview to another view and name it as you like.
Now add this code inside your didSelectRowAt
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let viewController = storyboard?.instantiateViewController(withIdentifier: "your_segue_name_here") as! YourViewControllerName
self.navigationController?.pushViewController(viewController, animated: true)
}
Please make sure that your tableview is connected with navigation controller.
To do that select your tableView then click on Editor -> Embed In -> Navigation Controller from your Xcode.
I hope it works for you.
: D
I am a beginner coder in swift. I am trying to create a tabbed application. For one of my tabs, I am creating a table view which has multiple rows each which have a different task (A good way to think of this is the facebook app, where each option in the more screen will take you to a separate view)
Now, my table is populated with an array:
let array = ["one", "two", "three]
I want to ask, that everytime that I tap on one of these rows, I would like to go a new view controller. How is this possible?
What I tried was performSegue with an identifier which I give in the storyboard, but then there would be an x amount of segues connecting to the table view? So I don't think this is right? :/
I know the contents of the array prior to generating the table, so If I know the array value, and the row being tapped, how can I navigate to a new view controller?
Edit:
When performing the segue between the controllers, I am using:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "showView", sender: self)
}
This of course will only connect to the segue showView however, how can i add multiple view controllers?
You need to simply compare which row is selected in tableView and then perform segue according to it.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let segueIdentifier: String
switch indexPath.row {
case 0: //For "one"
segueIdentifier = "showView1"
case 1: //For "two"
segueIdentifier = "showView2"
default: //For "three"
segueIdentifier = "showView3"
}
self.performSegue(withIdentifier: segueIdentifier, sender: self)
}
Add the following function to your controller.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
navigationController?.pushViewController(NewController(), animated: true)
}
Using Static Cells in a UITableViewController
Summary
An alternative is to use a UITableViewController with static cells. If you know already know the menu then you can just create static cells for each item.
In the storyboard you can connect a segue from each cell to their respective view controllers.
Example
I am writing a Xcode program in Swift. I have a tableview controller with some labels and an image per cell. They have their data from a first view controller. So far so good. Now i would like the user to tap a cell which opens a new controller which contains the same label and image data as the cell. With the following code the new controller opens, nonetheless I don't no how to transfer the data. If someone could help me I would be so so grateful.
Here are the codes that i tend to use:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "TableView"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TableView
let picture = pic[indexPath.row]
cell.label1.text = picture.name1
cell.photoImage.image = picture.photo
cell.label2.text = picture.name2
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let cell = indexPath.row
self.performSegueWithIdentifier("segue", sender: cell)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "segue"{
var row = tableView.indexPathForSelectedRow
let viewController = segue.destinationViewController as! vc2
}
}
PS:I have a segue from the image to the new controller with the identifier "segue".
PPS: Of course i have tried the following method: Send data from TableView to DetailView Swift but when i run my program I get an error with the information that my labels were unexpectedly found nil
You should not need to override didSelectRowAtIndexPath or call performSegueWithIdentifier to do this. Connect your segue in the IB file dragging from a table view controller's cell to the second controller. You should then pass the data to the controller in prepareForSegue, in the segue.destinationViewController. You set the public properties on that destination controller.
Also make sure your labels in your prototype cell have been connected in IB. If they are they, should not be nil. Set a breakpoint on the cellForRowAtIndexPath to verify this.
Unless you are talking about the labels in your destination controller. These also need to be hooked up in IB. You would then set them in prepareForSegue. You would get the appropriate data from the
let viewController = segue.destinationViewController as! vc2
var path = tableView.indexPathForSelectedRow
viewController.destLabel.text = arrayData[path.row].myData // or whatever data you have from your model.
I'm very new to swift. I added disclosure indicators to my TableView. I want to make the different disclosure indicators lead to different view controllers. Can anyone help me with this?
Connect your ViewController with multiple ViewControllers in your storyboard giving each storyboard segue an identifier. Then call self.performSegueWithIdentifier when you have identified which cell the user has selected. For example:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == 0 {
self.performSegueWithIdentifier("yourIdentifier", sender: self)
}
...
}
Update, see my comment below, as what I did wrong. Thought someone may benefit from all these newbie mistakes:) : I have a collectionView with section titles and cell titles (UILabels), which is dynamically fed in via cloudkit. I was able to get the code to finally work to select a cell and then send the cell's title to the 2nd ViewController's navigationItem.title property.
However, now the 2nd ViewController is reloading after it appears the first time. I embedded the first CollectionViewController within a navigation controller. And I created a push segue in storyboard from my prototype cell within the CollectionView to the 2nd ViewController, and provided an identifier for the segue. Any idea why it's reloading the 2nd ViewController again after appearing the first time?
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("selected", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "selected" {
let indexPaths : NSArray = self.collectionView!.indexPathsForSelectedItems()
let indexPath : NSIndexPath = indexPaths[0] as NSIndexPath
let theSelectedItem = sections[indexPath.section].category[indexPath.item]
let svc = segue.destinationViewController as TableViewControllerNew
svc.navigationItem.title = theSelectedItem
// I created the tableview controller in the storyboard, and then subclassed the UITableViewController, and set the storyboard tableview controller's class to the subclass in the identity inspector
}
Set the self.navigationItem.title = ... in the didSelect... method and then reset it to the old title in the viewWillAppear method of your first VC. This will save you from having to create a global variable in your first VC or having to pass the title as a property to your second VC, although both solutions should work as well.