I have a Tab Bar Controller which is the Initial View Controller, which also has a PFLoginViewController
that pups up if a user isn't logged in. The Login/Signup flow works fine.
The two tabs are
1. a UICollectionView
which I will refer to as IntroVC
from now on
2. a UITableView
which I will refer to as FeedVC
When a user clicks a photo in IntroVC
, a Show segue is triggered (via prepareForSegue
) that shows a 3rd screen (UIView
) which is technically not a tab. I will refer to this as the SelectVC
from now on.
NOTE: All of these screens are also Embed(ded) In a Navigation Controller.
The SelectVC
displays a photo, and there is a UIButton
that the user can press which triggers a Show segue and Unwind segue, to push the image into the FeedVC
. The reason I created an Unwind segue is because without it, the image would push into the FeedVC
(2nd tab) but the first tab would still be highlighted.
I fixed this with the Unwind segue, but I noticed I'm having a problem where after a selection, when I press the 1st tab (Intro VC) the Nav bar has a Back button, and the more times I use the SelectVC
button to push images, the more times I have to press Back in the IntroVC
. I'm very confused about how to fix this. It's apparent that I'm not hooking up the flow properly and it seems that the IntroVC
is being generated multiple times?
I get the following message in the console when I go through the segues in Simulator:
Nested pop animation can result in corrupted navigation bar
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
Any help would be greatly appreciated!
Relevant code below.
IntroVC.swift
@IBAction func unwindToIntroView(segue: UIStoryboardSegue) {
self.tabBarController!.selectedIndex = 1
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showFeedItem" {
let selectScreenVC = segue.destinationViewController as! SelectScreenViewController
let cell = sender as! UICollectionViewCell
if let indexPath = self.collectionView!.indexPathForCell(cell) {
self.navigationController?.popViewControllerAnimated(true)
selectScreenVC.currentVenue = venueItems[indexPath.row]
}
}
SelectVC.swift
@IBAction func pushSelection(sender: UIButton) {
var feedItem = FeedItem()
if let currentItem = currentItem {
feedItem.nName = currentItem.nName
feedItem.imageFile = currentItem.lgImg
feedItem.userName = PFUser.currentUser()!.username!
feedItem.saveInBackgroundWithBlock({ (success: Bool, error: NSError?) -> Void in
self.performSegueWithIdentifier("unwindToVenueView", sender: self)
})
}
}
I know this is weirdly structured, and if I'm missing information that is needed to fully understand - please let me know and I'll edit accordingly.
This solution uses an unwind segue to switch to a new tab and send it data.
Goal: Go from Blue to Yellow and pass data at the same time.
Blue View Controller (Descendant of Tab 1)
import UIKit
class BlueViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// this is the data that we want to send
let myData = "Hello from Blue"
// Get a reference to the destination View Controller
// and set the data there.
if let yellowVC = segue.destination as? YellowViewController {
yellowVC.data = myData
}
}
}
Yellow View Controller (Tab 2)
import UIKit
class YellowViewController: UIViewController {
var data: String?
@IBOutlet weak var dataLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
@IBAction func comingFromBlueUnwindSegue(segue: UIStoryboardSegue) {
// This may get called before the UI views have been loaded if
// the user has not navigated to this tab before. So we need to make
// sure that the label has been initialized. If it hasn't then we
// will have our chance to call updateUI() in viewDidLoad().
// We have to call it here too, though, becuase if the user has
// previously navigated to this tab, then viewDidLoad() won't get
// called again.
if dataLabel != nil {
updateUI()
}
}
func updateUI() {
// only update the label if the string data was previously set
guard let myString = data else {return}
dataLabel.text = myString
}
}
Control drag from the button to the Exit icon on the top of the source View Controller. Since we have already added the unwind segue code to the destination View Controller, it will show up as an option. Choose it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With