In my TvOS app I have a viewController with UISearchContainerViewController. Here is the tree of views:
and
The searchController looks good and work as needed. From this viewController I can go to another one and from there open another instance with initial viewController (with searchController). In this another instance the everything is well too. BUT, when i pop back to the first instance the keyboard disappearing and the tree looks like:
I think it's because the instance of the system keyboard is shared across the app. But i don't know how to fix that. Can you help me?
private var keyboardContainer: UISearchContainerViewController!
In initialController I did add
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
keyboardContainer.searchController.searchBar.becomeFirstResponder()
}
and it seems that fixed the issue.
Related
This question already has answers here:
Detecting sheet was dismissed on iOS 13
(13 answers)
Presenting modal in iOS 13 fullscreen
(27 answers)
Closed 2 years ago.
I have a simple flash card app I wrote for a friend of mine. I'm a hobby-est at best. It's essentially Tinder that you can flip the card over for a dead language. Everything has been working great up until the iOS 13 update with how Apple redid the Storyboards for flexibility.
My problem is my elegant solution to save userdefaults when exiting a view is no longer being called. This "carddeck" view controller is called when a button on another screen is pressed. To exit this same view controller before you would press a button that was tied to an "action segue - show" (not #IBAction) that would bring the view back to the "mainview" view controller. I tried the same action segue with "present modally." but no dice.
class CardDeckViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// called!
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
// called!
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
// not called when "return" on this screen is pressed;
// however, it still returns to the main screen it just doesn't save the user's score
}
Any help would be appreciated. My hope is there is an easier fix than redoing the entire storyboard. I see about UIModalPresentFullScreen. I'm no Swift guru so at this point I thought I would reach out to the pros. Hopefully this is too time consuming of a fix. Luckily I think the other views are not affected by this other than one more.
Thanks for reading!
A couple of things you might try:
It sounds like you're presenting the "main view" view controller again. Hard to tell without seeing your code but I think you should probably be dismissing "CardDeck" view controller in order to get back to your "main view" view controller.
Have a look at UIAdaptivePresentationControllerDelegate. This stackoverflow post covers the change and iOS 13 solution.
I had some similar issues with iOS 12 view controller lifecycle behavior being changed in iOS 13.
I suggest considering NotificationCenter if nothing else works. You broadcast from your current view controller and someone like your AppDelegate can receive the message and act on this. It's not always the best tool for the job but it can help in certain situations.
Not related to your question but your calls to super super.viewWillAppear(true) should probably be super.viewWillAppear(animated) so you're not disregarding the method argument.
The answer was at the bottom of this question:
Presenting modal in iOS 13 fullscreen
I just had to redefine the storyboard UI property from Automatic to Full Screen.
I am building a pin entry viewController very similar to the iOS one you see when you go to Settings->TouchID and it prompts you for pin.
I am trying to mimic its behavior of presenting the iOS keyboard along with (at the same) of the modal presentation of the pin entry viewController. I have noticed other applications like Venmo are able to achieve this as well.
How can I achieve this behavior? My pinEntryView is a textField. I have tried sending it the becomeFirstResponder message in viewDidAppear, and this seems to work; however, it will present the iOS keyboard AFTER the viewController modal presentation has finished. I want the presentation to occur at the same time to give the feeling that the iOS keyboard is actually baked-in/part of the ViewController.
I have tried sending the becomeFirstResponder messages in viewWillAppear, viewWillLayoutSubviews as well, but these are not stable solutions. Sometimes the keyboard is displayed and sometimes its not. Is there anyway to do this?
I made the test by setting becomeFirstResponder in the viewDidLoad and it is working fine.
I have one button that calls the modal, and that modal has the next code:
override func viewDidLoad() {
super.viewDidLoad()
self.textField.becomeFirstResponder()
}
It has no unexpected behavior.
I believe I have had this issue before, and it has quite an interesting solution. What you want to do is call becomeFirstResponder in viewWillAppear before calling super 😱.
override func viewWillAppear(animated: Bool) {
textField.becomeFirstResponder()
super.viewWillAppear(animated)
}
Then when you call super the first responder is already set, and then iOS picks up this state and includes the keyboard appear animation in the appearance transaction.
Hopefully this can help you too.
I encountered a problem while trying to present a new view controller within a storyboard using following code:
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("ViewControllerIdentifier")
self.presentViewController(viewController!, animated: true, completion: nil)
The view controller does appear, but shows for some reason only two buttons, no other elements.
What have I tried so far:
Loading the view controller as initial view controller to see if the
problem remains.
No, all elements are at the right position.
Switching animated from true to false. Problem still remains
Printing the hidden attribute as well as x and y positions. Hidden
is false, and the positions are what they are supposed to be
Cleaning and rebuilding the project, since this seems to fix 99% of
all strange bugs based on my experience. Sadly this helped not this
time
Setting hidden first on true, then on false. Resetting the attribute
does not help.
Using CFRunLoopWakeUp(CFRunLoopGetCurrent()) . Does not help
either.
I have a simple drawing of what my view looks like attached.
As stated, the view controller is shown perfectly fine when I load it as initial view controller, but only the buttons are shown when using the code above.
ViewDidAppear is called as well.
I am using Xcode Version 7.2.1
EDIT:
As requested by comment, this is my code for the view controller to be presented:
import UIKit
class myViewController : UIViewController {
#IBOutlet weak var myImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
}
Edit:
I found a solution to this problem:
By creating the transition within the following block.
dispatch_async(dispatch_get_main_queue(),^{
});
It appears that my problem was, that the lines that trigger said transition weren't executed on the UI thread. I still have no idea why this lead to the behaviour explained above, but at least there is a solution.
In my experience problems like this can be down to your auto layout constraints being messed up or not quite as you need them (although the fact that it presents correctly when it is the default might suggest I am not headed down the right path).
Are there any warnings in the storyboard editor that suggest the constraints are not correct? I would also suggesting using the view debugging feature to help troubleshoot. Click on the circled icon when your app is running to show your view hierarchy and then try to find the views you think should be there. It also allows you to look at constraints, so that might help with point 1 above as well.
Right now I'm doing this:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated);
self.loadObjects()
}
But every time I use loadObjects(), the screen briefly flashes. I don't know how to fix it. I am using a TabBarController (no segues between views), so each view is only loaded once, and I want to update each view when I navigate to it. loadObjects() works, it just creates this annoying visual bug. I assume that the old view is cached and is desplayed before the new one is loaded, and that's why I see this flash. Any suggestions?
I don't know what is wrong with my code. i have developed app successfully and all the things working fine except when i launch app first time, In side first navigation controller, the pop animation is not working fine. it seems that Pop without animation. and its working fine when i changed the tab and come back on first tab. and doing push-pop then its working fine.
I tried to figure out problem since week. but could't get success because of lengthy code. I have tried the same animation with creating Tabbar Demo and its working fine.
My app has following hierarchy.
UINavigationController --> UIViewController --> UITabbarController --> Four UINavigationController --> UIViewControlle.
I have taken UITabbarController in my storyboard.
I know that i asked the question and also provide solution for same. I have asked this question long time ago and i am not getting any solution for this because there is illogical bugs. Not every Tabbar base application have same. Here i am adding solution that is result of long time debugging and i found that even single line can break your project.
Actually i have added UITabbarController from storyboard and programmatically created UITabbarController class and type cast it with UITabbarController inside storyboard.
Here my problem is, i forgot to write [super viewDidAppear:animated]; inside -(void)viewDidAppear:(BOOL)animated method. so i will break pop animation first time then it will work fine.
After getting this solution, even i don't know how this line affect whole code. but i don't want the other people to waste their time to find out such single line (unexpected issue) problem. so here i am adding this code.
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
For Swift 5
Depending on #Jatin Patel - JP answer
Create custom class for your TabBarController
Add this Code in your UITabBarController file
class MyTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
}