I have simple app. My tableViews contains some words; I post data in post screen and I want to get back to the first tableView screen. I have use a segue for this. The problem is that each time after posting, clicking the post button opens a new tableView over the post screen. I want to return to the original.
Table View Screen -> Post Screen -> New Table View Screen
But I want
Table Vievscreen <-> Post Screen
I had the same issue.It is resolved now. Please let me know if this helps.
I already have a segue linked from table view cell to another view with name DynamicSuperView
func tableView(_tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
//Remove the below line from this function as it will perform segue.
//performSegue(withIdentifier: "DynamicSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
// This will actually perform your segue
var DestViewController = segue.destination as! DynamicSuperView
let selectedRow = tableView.indexPathForSelectedRow?.row
DestViewController.labelText = names[selectedRow!]
}
Hope this helps to somebody.
We need a LOT more information to what is provided. However this may get you started in the right way.
If you are using a navigation controller, put this in your posting view code:
navigationController!.popViewControllerAnimated(true)
If you are NOT using navigationController but instead showing the view modally, then use the following in your posting view code:
dismissViewControllerAnimated(true, completion: nil)
Most segues create a new instance of a view controller and display it on top of existing view controllers.
If you are adding a view controller to a navigation stack with a push, you want to do a pop as described in JAL's comment.
If your segue is modal, you want to do a dismissViewController:animated:
You could also set up an unwind segue, although that might be overkill for this simple case.
I'm getting the same issue here, but I realize that I just did wrong on control+click, I dragged from cell, the correct must be from tableview
I hope this help some one
Related
my Storyboard looks like:
User can go directly from the 1st screen to the 4th. The fourth screen contains tableView, with XIB cell design. I want user to be able to tap on a cell and get to the 3rd screen and send some data with that. I know this should be done in didSelectRowAt. But is it even possible?
Yes it is possible.
Create a segue. In your storyboard, ctrl-drag from the first button on top of your 4th screen to anywhere on your second screen. You should see a new segue created in your storyboard.
Give the segue an id. Click on the newly created segue, in the right panel, set the indentifier attribute under the Indentity Inspector tab.
Perform the segue. In your didSelectRowAt, add the following line:
self.performSegue(withIdentifier: "THE_ID_YOU_ASSIGNED_IN_STEP_2")
Send data to the destination segue. In your screen 4 view controller, add the following function:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "THE_ID_YOU_ASSIGNED_IN_STEP_2" {
if let destinationVC = segue.destination as? YOUR_SCREEN_3_VC {
// Send data to your VC, such as assigning values
}
}
}
I have a Navigation Controller with a UITableViewController.
When a user selects a cell on the TableViewController, it pushes to a new View Controller with a Table View inside. The user then selects a cell and the data gets passed back via an unwind segue.
The problem is I get this error when using a search bar before selecting the cell. Here is what the console says:
popToViewController:transition: called on <UINavigationController 0x7fc8ab856e00> while an existing transition or presentation is occurring; the navigation stack will not be updated.
Code from View Controller I'm unwinding from:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let cell = tableView.cellForRow(at: indexPath) as! MonsterSpriteCell
let monster = monsters[indexPath.row]
selectedMonster = monster
if isTeamBuilding {
// **ERROR OCCURS HERE**
performSegue(withIdentifier: "saveToTeamBuilderTableVC", sender: cell)
} else {
performSegue(withIdentifier: "showMonsterDetail", sender: self)
}
}
Here is the link the the project. The View Controller I'm unwinding from is Browse View Controller. The View Controller I'm unwinding to is TeamBuilderViewController
https://github.com/emanleet/monsterpedia
EDIT: I think it might be relevant to note that the segue unwinds to TeamBuilderTableViewController, which is a View Controller that is inside a container as a part of another view controller. Does anyone know if this might be why my unwind segue isn't working?
Two step thing, first dismiss the search controller presented view controller, then, do your thing.
yourSearchController.dismiss(animated: true, completion: {
self.performSegue(withIdentifier: "yourUnwindSegue", sender: self)
})
The SearchController is presenting an empty view controller
If you print the presentedViewController in didSelectRow.. when the search is active you will see a view controller.
that means you’re trying to perform segue from under the current presentation. You should dismiss the SearchController before performing any segues or presentations.
Also in this case you don’t need a SearchController since you’re only using the SearchBar for filtering.
Instead, put a SearchBar in the tableViewHeaderView and use its delegate to do the filtering and instead of checking if isActive to access the complete list vs. the filtered results, just put the whole array in the filter when the text is cleared and always access the filtered results.
I have implemented the SWRevealViewController into my app to give my app a nice side menu. My main (home) screen for the app is TableViewController.swift - this is also the only place you can access the side menu from. The side menu all works perfectly. Here is an image to show what it looks like:
The 5 options you can see in the menu, are created in a tableView I want them to all link to other view controllers. I have currently achieved this using the method they showed in the tutorial for this side menu, which is to create a segue of reveal view controller push controller. This all works.
The problem
When you press one of the options, It reveals the new view controller as the sw_front, therefore, I have lost access to the main (home) screen. For example, the VC linked to the first option 'Films I want to see' is just a plain green VC. The image below shows what happens after I have pressed that option and then tried to go back:
So you can see, the VC that appears at the front is no longer my main (home) screen.
I'd like to know is there away I can set this up so when you press an option in the side menu, it opens up the new VC over the top of the side menu, so when you close down that VC, it still shows the side menu open with the Main (home) screen in front.
I hope that makes sense. Please ask if you need to see any of my code.
I managed to find a solution!
I first created my 5 new view controllers (one for each option in the side menu)
I then linked each cell to it's view controller by creating a 'Show' segue. So my storyboard now looked like this:
I created a segue identifier for each segue.
Then in my sideMenu.swift file, I added the following:
Created variables to store the identifiers for the segues.
// Mark:- Sets the side menu segue identifiers
let smOption_One = "toFilmsIWantToSee"
let smOption_Two = "toSearchForAnyFilm"
let smOption_Three = "toMeetTheTeam"
let smOption_Four = "toContactUs"
let smOption_Five = "toTermsOfUse"
I then added the didSelectRowAtIndexPath method, and added performSegueWithIdentifier for each of my segues.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier(smOption_One, sender: indexPath)
self.performSegueWithIdentifier(smOption_Two, sender: indexPath)
self.performSegueWithIdentifier(smOption_Three, sender: indexPath)
self.performSegueWithIdentifier(smOption_Four, sender: indexPath)
self.performSegueWithIdentifier(smOption_Five, sender: indexPath)
}
And finally, added the prepareForSegue method. Inside this method I did a check for each identifier, and then segued to the destinationViewController.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == smOption_One {
segue.destinationViewController as! FilmsIWantToSeeViewController
} else if segue.identifier == smOption_Two {
segue.destinationViewController as! SearchForAnyFilmViewController
} else if segue.identifier == smOption_Three {
segue.destinationViewController as! MeetTheTeamViewController
} else if segue.identifier == smOption_Four {
segue.destinationViewController as! ContactUsViewController
} else if segue.identifier == smOption_Five {
segue.destinationViewController as! TermsOfUseViewController
}
}
This perfectly creates a segue to the correct view controller, depending on which option I press, and presents it over the top of the side menu, so when I dismiss that view controller, it still shows me the side menu, and therefore allows me to get back to my main screen.
Not sure if there is an easier way of doing this, but it certainly works how I needed it to. Written in Xcode 7.2 with Swift 2.
This seems to be a common problem, but none of the many solutions I've tried have seemed to work (or I'm not executing them properly).
I've got an image on FirstImageVC, I push a button to bring up a new view collection view controller with some custom images, the user selects one, and I want to send that image back to the FirstImageVC to overlay the original image, sort of like a sticker.
I just can't get it to execute a segue of any kind on selecting an image. Here's what I'm sort of working with in the second view controller. And it seems I may need to be adding something to the original VC, too, no?
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
prepareForSegue("backToFirstSegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "backToFirstSegue"{
let vc = (segue.destinationViewController as! FirstImageVC)
vc.Delegate = self //Include this line
vc.chosenGhostPhoto = bgGhostImage?.image
}
}
EDIT 1: Here's what I did to get the unwind to work, though it's not carrying back the image selected from the collection view, which needs to be called chosenGhostPhoto.
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("unwindToFirstSegue", sender: self)
}
This is how you can do this:
Step 1: Add a delegate variable on your second view controller. Please name it delegate and not Delegate - owing to naming convention.
Step 2: Define a protocol and add functions that you want your second view controller delegate to perform. Say func selectedImage(image : UIImage)
Step 3: While pushing second view from first view controller, set your first view controller as delegate of second view controller. Something like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "secondSegue"{
let vc = (segue.destinationViewController as! SecondImageVC)
vc.delegate = self
}
}
Step 4: In your second view controller once image is selected call delegate of second view controller. Below function needs to be triggered on tap on the image on second view controller.
fun imageSelected {
self.delegate.selectedImage(bgGhostImage?.image)
}
Step 5: Implement selectedImage in your first view controller and use the passed image.
An unwind segue (sometimes called exit segue) can be used to navigate back through push, modal or popover segues (as if you popped the navigation item from the navigation bar, closed the popover or dismissed the modally presented view controller). On top of that you can actually unwind through not only one but a series of push/modal/popover segues, e.g. "go back" multiple steps in your navigation hierarchy with a single unwind action.
When you perform an unwind segue, you need to specify an action, which is an action method of the view controller you want to unwind.
For your reference this is quit similar question and might help in understanding unwind segue
I must be doing something wrong here.
I have a UITableView, and have implemented a UISearchController.
I have a Prototype cell linked to the details screen and pass the selected value in the prepareForSegue method.
For the normal view controller, all works OK, a row is selected and the details screen pushed (i.e. slide in from right).
However when there is an active search, using the UISearchController, the details screen is presented modally (i.e. slide up from bottom of screen) without the UINavigationBar (so there is no possibility to go "back")
I am not using didSelectRowAtIndexPath since I have used storyboard to push the details screen
Why is the presenting animation different when the same code in "prepareForSegue" is being correctly called in each case:
// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier! == "PresentContactDetail") {
// pass person details from selected row
if let selectedRow = self.tableView.indexPathForSelectedRow()?.row {
let selectedPerson = self.visibleResults[selectedRow]
(segue.destinationViewController as ContactDetail).personRecord = selectedPerson
}
}
}
Any suggestions gratefully received.
in ViewDidLoad of UITableViewController set
definesPresentationContext = true