I'm having this weird situation over my app. I'm calling performSegueWithIdentifier over the main thread :
dispatch_async(dispatch_get_main_queue()){
self.performSegueWithIdentifier("toFrame", sender: nil)
}
I've set breakpoints thru the process, and even cleaned prepareForSegue.
Only for the first time when i'm calling this(to this specific VC),it's delayed for about 6 seconds, and than moving to the VC. After this delay, if i'm navigating back and forth, it runs smoothly
Any suggestions? Ive tried everything :\
It can be fonts issue: if you select them in IB and didn't check target membership - system will look for them before retrieving default font - and
thus will create delay before presenting controller.
Please check font's target membership.
It’s famous bug with modal presentation:
http://openradar.appspot.com/19563577
Related
I am getting this strange error in iOS 9 only:
[UIWindow endDisablingInterfaceAutorotationAnimated:] called on UITextEffectsWindow: ...without matching
-beginDisablingInterfaceAutorotation. Ignoring.
Anytime I dismiss the keyboard interactively by dragging down from within my collectionView. I don't get the error by dismissing the keyboard with a tap gesture or pressing enter. It is very frustrating. Even if I don't observe any keyboard notifications, I still get this error on this interactive keyboard dismissal. I wonder if anybody else has come across this error and found a solution. I have an inputAccessoryView consisting of a textView mounted on the keyboard.
I had the same problem on iOS9 but with a tableView. I implemented this along with self.tableView.keyboardDismissMode = .Interactive and it worked for me.
// Dismiss keyboard when scrolling
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
textView.resignFirstResponder()
}
Things to Check
It appears that several other SO users have had similar experiences under a variety of conditions. Check out this thread. Since there could be a lot of things happening that cause this problem you might want to review the thread provided to see if you can find a matching use-case. It's unclear how you are dismissing the keyboard but you might want to call something like this from a method or as a gesture recognizer (rather than a direct dismissal from a specific object):
UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)
From the thread provided, the nature of the issue in most cases was a duplicate call during presentation or dismissal of the view. I've also seen issues where I have a storyboard segue connected (or in some cases it was removed but the xml was still in the storyboard code view) and a code-based segue (performSegueWithIdentifier...) for the same animation (which causes two display/dismiss calls).
I'd look at the log to see what calls are being logged just before the error and then do a find in the log view to see if there is a redundant call. Again there could also be a redundancy in the behaviors/animations/layouts on the storyboard and calls made in the code.
UPDATE
The comments from the OP, reminded me that in some cases especially those involving calls during presentations/dismissals, I have seen instances where the only way to successfully have a developer function work is to wrap it into a dispatch_async call. There are some critical systems calls that appear to not work well if developer code is introduced during the same frames.
A concrete example is this call which is within willMoveToWindow. In this case I have a weakSelf reference to the view and simply review the newWindow for nil value (indicates the view is being dismissed) before calling my code.
So in this example if one removes the dispatch call, then the developer code would cause the entire app to crash. I'm guessing that the system transition calls (related to transposing to/from the window) may be conflicted with whatever the developer requests at that time.
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//the saved flag is true only when user hits the done button
if !(weakSelf!.saved) {
weakSelf?.completeNotes(nil)
}
})
I encountered this issue and it messes up my view. This is how I solve it.
I was having a viewController being presented on textFieldShouldBeginEditing. In the viewController, a textField was set to becomeFirstResponder in viewDidLoad.
The solution for me is to move the becomeFirstResponder to viewDidAppear.
I am new to iOS and using storyboards for the first time. When my app starts it checks back with the a server app I have written to see if the saved credentials are authenticated and I then in my AppDelegate class I then attempt to show the appropriate scene in the app's storyboard - MainMenu if authenticated or a Login Screen if not authenticated.
I have tried using instantiateViewControllerWithIdentifier on the storyboard and also the performSegueWithIdentifier on the initial NavigationController which is set to be the "Initial View Controller" to display the appropriate view..
However with both methods only the blank navigation bar shows and I am unsure where to go from here.
If there was some example code on how others manually manipulate storyboard scenes and viewcontrollers that would be great. Am I maybe putting the code in the wrong place (ie should it go into the first View Controller) or should that not matter? No exceptions are raised and I seem to have access to instantiated objects as required.
I am thinking I need to understand the operation of the app delegate's window more, or maybe should I focus on manually loading the storyboard by removing it's reference from the InfoPlist settings?
Any thoughts would be greatly appreciated.
From my (admittedly haphazard) understanding of storyboards (at the moment), you should have two named segues going from a first viewcontroller, and then you can simply trigger one or the other as need be (I presume there's some sort of "loading/authenticating" screen, however brief?)
if (success) {
[self performSegueWithIdentifier: #"MainMenuSegue" sender: self];
} else {
[self performSegueWithIdentifier: #"LoginSegue" sender: self];
}
To debug, I'd set up buttons on the initial viewcontroller just to be sure the segue linkings/etc are proper.
You really shouldn't need to instantiateViewControllerWithIdentifier unless you're working around segue/storyboard limitations. I think.
I've put the performSegueWithIdentifier in my app's first viewcontroller's viewDidAppear (not the best idea, I think; but that's sort of the soonest it should happen? and I would hedge towards saying it should be triggered somewhere in the viewcontroller stack, not from the appdelegate, but I haven't tested that).
After some research on the web without success, I come here to ask you the question about my warning.
Actually, I have a view V1 with a navigation controller and I want to push a modal view V2 when V1 has finished loading.
So I use the performSegueWithIdentifier method (I'm using storyboard).
Here is my code:
[self performSegueWithIdentifier:#"showConnexionViewSegue" sender:self];
And when I compile, I got this warning:
Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0x6849b30>
Can anyone help me?
It sounds like you may be performing the segue in -viewWillAppear: thus generating two -viewWillAppear: messages without 2 corresponding -viewDidAppear messages.
Try performing the segue in -viewDidAppear.
I had this problem, but what I had done is on a UIViewController I had linked a Segue from a UIButton and also coded it into a nextBtnPressed: function, so I was actually pushing two new UIViewControllers on the one button press. Limiting it to just the one segue fixed it. But it took some investigating to see that I had done this double up.
'Unbalanced calls to begin/end appearance transitions for '
Says an animation is started before the last related animation isnt done.
So, are you popping any view controller before pushing the new one ?
Or may be popping to root ? if yes try doing so without animation
i.e. [self.navigationController popToRootViewControllerAnimated:NO];
And see if this resolves the issue, In my case this did the trick.
The reasons for this are manifold and are very specific to the context and the programming. For example, what I was doing was
initialising a sound file, playing it (asynchronously) for 1.4 seconds,
making an image move across the screen using animation timed to last 1.4 seconds and,
with a timer set to 1.4 seconds after step 2, pushing a viewcontroller.
What i discovered is that if I DO NOT have the instructions for these 3 steps one after the other (if I mix them up), then I get the error "Unbalanced calls...". Also, if I time the push of the viewcontroller to less than 1.4 seconds, I get the message as well.
So, check that the sequence and timing of your program instructions are correct.
I have traced a problem in my iPhone app code to the viewDidAppear method not always firing. When you start the app the event fires as expected. However if I close the app using a phone capable of multitasking and reopen in. My viewDidAppear events no longer fire.
My views are loaded from Nibs and I use viewDidUnload to clean up (release and nil all outlets). My views are nested in side and tab bar then navigation controllers. I looks like the events aren't wired up properly when the nibs reload. Any idea on what I'm doing wrong/missing and how I can fix this?
Thanks in advance.
UPDATE I do not mean the event is not fired when the app first comes into the foreground. I mean the event never fires again. Even when changing between tabs or moving though the navigation views.
Example:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(#"viewDidAppear called");
}
This code is placed in two views, each on different tabs. Each time I swap between tabs "viewDidAppear called" is written to the log. When I close and reopen the app and swap between tabs this no longer happens. Other button events fire normally.
Btw, the viewDidUnload method is really badly named btw -- it's not an 'opposite' to viewDidLoad, it's only called if there was a low memory situation and the view for that controller was unloaded due to not being visible at that time.
(ORIGINAL, NOT SO RELEVANT ANSWER:)
Please see my answer to this similar question:
Why does viewWillAppear not get called when an app comes back from the background?
Basically, viewDidAppear gets called after your UIViewController's view was added to the application's UIWindow heirarchy. Backgrounding then restoring the app doesn't change your view in that respect, so viewDidAppear doesn't get called -- it's correct behaviour, and not a bug. Check out the API docs for UIViewController.
Found it.
While not new to programming I am new to iPhone development. On researching this problem I found it was not recommended to call the viewWillAppear and viewWillDisappear methods manually.
My viewWillDisappear methods resign any keyboards if shown, when my app enters the background it loads a splash screen ready for when the app re-enters the foreground (there is some logic I need to do to work out what the user is shown on restarting the app and I can do this under the splash screen).
As viewWillDisappear is not called when the app goes into the background to make sure no keyboards appeared over my splash screen I was calling viewWillDisapper in the applicationDidEnterBackground method. I guess this also un-registers my events.
By adding viewWillAppear to my applicationDidEnterForeground method my events started firing again. Lesson learned, I will refactor this so I don't call these events manually.
Thanks for the help.
My top level view immediately Pushes my SplashView in it's ViewWillAppear method. In some conditions, the SplashView pushes an additional view, which is properly popped. When this occurs the Top Level view never appears.
However, the code in the Top Level is running (it has a timer that occurs every minute which writes to the log). And if I trap it in Debug I can see the code executing. Additionally, in the Top Level ViewDidAppear if I log the [self navigationController].visibleViewController.nibName the name of the Top Level appears.
If I don't do the Push in the SplashView everything works fine.
The app is forced into Landscape mode, and each ViewController contains return UIInterfaceOrientationIsLandscape(interfaceOrientation); for the shouldAutorotateToInterfaceOrientation method.
I'm baffled and don't know what to do next. Suggestions?
While I did not exactly determine why this was occurring, I have resolved the problem. Here are some things I noticed in further debugging:
I noticed the message wait_fences: failed to receive reply: 10004003 in the log. Scanning blogs on this didn't help me much, but it led further down the path. References to it showed issues with UIAlertView, which I did have in the Splash view.
I added ViewDidAppear logic to the Splash view, then found this was getting called twice! I then added logic to act on this only once and my problem was solved!
So apparently there is some quirk with the View getting called twice that was creating my initial issue. References I found implied this was an 'old' OS issue, but I am using xCode 3.2.3 and SDK 4.0.2, so maybe it's back! Gee, I don't recall it doing this with SDK 4.0.1!