Segue very slow on first call in iOS - ios

I have a few simple Segues --> Show(e.g. Push)
On some Segues the first time calling the Segue I get a delay (about 2 Seconds).
There is no Code being Executed on shouldPerformSegue and prepare.
ViewDidLoad of the next View gets called after the Delay.
When the delay occurs I often get this warning:
objc[3993]: Class PLBuildVersion is implemented in both...
There seems to be no solution to this though --> Link
I have also tried calling the Segue Manually like this:
DispatchQueue.main.async {
self.performSegue(withIdentifier: "theIdentifier", sender: theSender)
}
Is there any way to make this more responsive?
Thanks!

Try to embed view controller in a navigation controller

Related

Unwind segue (still) not working

I'm trying to get an unwind segue working (in Swift) and have read through all the "unwind segue not working" posts I could find but haven't yet found whatever it is I'm doing wrong. So.
I have a UISplitViewController with a UITableViewController as my left-hand menu and two UINavigationController+UITableViewController detail views that I'm switching between. Segue-based navigation from my left-hand menu works fine. It's when I want to programmatically unwind that things do not.
I've created an #IBAction function in my first view controller, the one I want to unwind to, like this:
#IBAction func unwindToDocuments(_ segue: UIStoryboardSegue) {
}
(My first view controller is my "Documents" view.)
Then, in the second view controller, I connect an unwind segue to the exit node with identifier unwindSegueToDocuments and action unwindToDocumentsWithSegue:.
It's my understanding that should be all I need to do. However, when I try:
self.performSegue(withIdentifier: "unwindSegueToDocuments", sender: self)
it doesn't do anything. It stays in my second view controller as the detail view.
I'm using self.performSegue there because I'm in a closure. It's some network work so it's being done in a DispatchQueue.async() background queue. However, the performSegue call is in a nested DispatchQueue.main.async() block at the end. (Or, rather, I've tried it both/all ways, and still can't get it to unwind.)
Nothing helpful appears in the console.

Same view controller loads twice

I've read several posts on this issue but none of them solved my problem.
I'm coding an app where I have to click on a button ("Prepare") to go to the following ViewController. When the button is clicked, it also passes data between the two view controller.
The problem is, when I click the button, the following ViewController loads twice. Thus, if I want to go back I have to go back through two same ViewController.
I've checked the segue, the class names and files names but nothing fixes it.
I've also created a new project and rewritten all the code from the beginning but in the end, it still doesn't work.
However, I've noticed that the problem showed up when I added the prepare(forSegue:) function and the performSegue function. Without it the ViewController only loads once. But of course, I can't get the data passed between the views without it...
Here is the screenshot of my two view and the code of the two functions :
First view
Second view
// Prepare the segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "prepareSegue" {
let timerViewController = segue.destination as! CountdownViewController
timerViewController.timeInterval1 = waitingTime
timerViewController.timeInterval2 = shootingTime
timerViewController.lastSeconds = lastSeconds
timerViewController.currentTimeInterval = waitingTime
}
}
// Prepare the timer when the button is pushed
#IBAction func prepareTimer(_ sender: Any) {
performSegue(withIdentifier: "prepareSegue", sender: self)
}
Probably, when two ViewControllers appear it's because you have:
A segue on Storyboard which start directly from a Button
IBAction attached to the button where you call a performSegue of the same Segue
To fix this problem, you need to create a Segue which start directly from ViewController. After you can use the IBAction and the performSegue
You have added a seague but also an IBAction. If the seague is defined well in InterfaceBuilder it will perform and call your method. The IBAction is the alternative way for connecting an Action to a button. If you use both, you have two actions.
Without the rest of your project to check, one thing it could be is a completion closure which contains the performSegue(...) statement is called twice, so the performSegue statement is literally run twice. How might this happen?
If you have a networking call inside the closure which contains performSegue command, and the networking call has a closure which calls completion(...) twice, then you could get either the segue occuring twice or even recursively!
It's rare this will be the case, or in your instance, but this type of problem can be uncovered by using lots of breakpoints and following the "bouncing ball" to see the completion() calls occuring more than once.

"whose view is not in view hierarchy" on Segue

I try to perform a segue programatically from one view to another, way after it's been loaded (server sends an order to proceed) but it won't happen because "whose view is not in view hierarchy". Any ideas on how to solve it?
P.S. I don't perform any segues from viewDidLoad() method, all of them are performed from a method which is also called from another method in this class (which reads a dictionary, sent from the server). Also I tried to perform segues like this
dispatch_async(dispatch_get_main_queue(), {
self.performSegueWithIdentifier("seg_wait_ready", sender: self)
})
and just like this (even though I know this is wrong):
performSegueWithIdentifier("seg_wait_ready", sender: self)
None of these work, I still get the same warning.
I solved this issue by changing the logic of how my application changes VCs. Now I do it directly through the delegate by doing the following (roughly):
delegate.window!.rootViewController = destinationViewController
It cost me all the system transition animations but I like to do custom ones anyway. But remember to keep it in main queue. To do it safe put it in the main queue manually like this:
dispatch_async(dispatch_get_main_queue(), {delegate.window! ... })

Blank ViewController after programmatically performing segue in XCode

In my XCode project, which implements MultipeerConnectivity framework, I have a segue between two ViewControllers which is triggered programatically after MPCHandler successfully establishes connection with another peer. After segue is performed, the destination VC appears being completely blank (all white). However, if I try to access the destination VC with help of a button (with segue dragged directly from the button to the destination VC), it appears as it should.
Here is the line of code, which performs the segue:
performSegueWithIdentifier("seg_wait", sender: self)
So, yeah, I know how to perform segues and, yes, I made sure identifier is unique and is the same as in storyboard. I had tons of segues in many of my projects, and that's the first time I've faced a problem like this. Did anyone face a problem like this? Any ideas on how to solve it?
UI updates always have to be done on the main thread ("the law"). So try to wrap the call:
dispatch_async(dispatch_get_main_queue(), {
performSegueWithIdentifier("seg_wait", sender: self)
})

IOS7 - performSegueWIthIdentifier does not have any effect

I have a problem in iOS7 where I am calling a segue with performSegueWithIdentifier (I have code just like this that works just about everywhere else), then I log the segue in prepareForSegue, then I log again the view controller (VC) that the segue is supposed to push to the top.
prepareForSegue gets called appropriately and the segue has the correct string as its identifier property. Yet the VC that it is supposed to push to the top never gets initialized nor viewWillAppear gets called.
The segue I am talking about, which is the only one that does not work (all the other ones work in both ios6 and 7), is the one leading form the center VC to the right VC. By the way, this works flawlessly in iOS6.
What could be the cause?
the code:
-(IBAction)gotoMainMenu:(id)sender{
DLog(#"DifferentName");
[self performSegueWithIdentifier:#"DifferentName" sender:self];
}
Get in the habit of not wiring up segue's to buttons. Wire them up to the VC and then in the touchUpInside action, fire off the performSegueWithIdentifier.
I had the same issue and solved it as follows. In view A I had a segue that was triggered by a button (UIButton) and the button was also connected to an action in my controller. When I clicked the button in View A, View B would appear as expected. However, when I tried clicking a button in View B to go to View C nothing happened just as you described above.
In my case the issue was resolved in View A. I removed the segue that was tied to the button and let the IBAction that was associated with the button handle calling the performSegueWithIdentifier, then I created a new manual segue that was only tied to the view and voila things worked as expected again.
In short, I guess make sure you don't have both and action and a segue linked to the same button. Hope this helps.

Resources