I wrote a custom UIViewController for showing slide-up menu. Every time calling present(thisViewController) will show up the menu with animation and background is black transparent with alpha 0.5.
But I got problem that every first time the viewController is present, animation is not fully run, background color seems no transparent, and the slide menu is not shown the whole menu that there is one line outside of screen.
I searched the internet and found the reason is the animation not done, because the viewController is just initialed and animation is too fast shown. If I dismiss and present it
again will show as what I expected.
So I want to have a method to pre-initial the slide menu ViewController that it can run viewDidLoad before I present it. Is there a way to do this?
Update:
I call UIView.animate() in viewWillAppear(). I think the first time it ran viewWillAppear() too short time that it just initialized UIView and immediately animated, so it interrupted in the animate action. When the second time presenting this viewController, it showed the animation fully because it was shown before.
I add the views in viewDidLoad() but it won't be called until presenting the viewController.
Hmm.. I want to have a method to let the slide-up menu viewController pre-do viewDidLoad() in the other viewController.
#Shadowrun Thank you.
In A UIViewController, I initial the SlideMenu ViewController, and make the SlideMenu call ViewController.loadViewIfNeeded() in viewDidLoad()
class viewController: UIViewController {
var slideUpMenu = SlideMenuViewController()
override func viewDidLoad() {
super.viewDidLoad()
slideUpMenu.loadViewIfNeeded()
}
func pressButton() {
present(slideUpMenu, animated: false)
}
}
It shows perfectly.
Related
Trying to build my first app. Using a TableView to present 4 different sections. Each section has its own type of cell, which is defined in a .xib file. In the last section of the TableView, a cell is presented with two buttons, plus and minus.
When, for example, the plusbutton is pressed, it calls the following code in the class related to the cell:
// link to the viewcontroller with the tableview in it
let mainViewController = ViewController()
// func called when plusbutton is tapped
#IBAction func plusButtonTapped(_ sender: UIButton) {
// viewcontroller that should popup when the button is tapped
let popup = PopupViewController()
let sbPopup = SBCardPopupViewController(contentViewController: popup)
// call to show()
sbPopup.show(onViewController: mainViewController)
}
// show() function that is called
public func show(onViewController viewController: UIViewController) {
self.modalPresentationStyle = .overCurrentContext
viewController.present(self, animated: false, completion: nil)
}
When I tap the button in the simulator, it should present the PopupViewController, but the following warning shows:
Warning: Attempt to present "balance1.SBCardPopupViewController: 0x7fdf8752cb20> on <balance1.ViewController: 0x7fdf8743cac0> whose view is not in the window hierarchy!
I tried researching the warning and found some other topics relating to it. None of the solutions worked for me. Maybe it has to do with the fact that I'm calling the plusButtonTapped() from a cell defined in a .xib file?
I followed this tutorial on youtube: https://www.youtube.com/watch?v=9yUIOjykPDU
All went wel untill 10:36 where the show() is called on the same VC where the button lives that calls the function. In my case the plusButton that calls the show() function lives on a cell that is defined in a separate .xib file and thus not on the (main) VC (as shown in the tutorial). Does this have anything to do with the problem I am facing?
The error message looks like it's right. Just looking at your code the "dangling" mainViewController hasn't been added to a window yet.
// link to the viewcontroller with the tableview in it
let mainViewController = ViewController()
This comment above this line seems to indicate that it's a link to the parent viewcontroller, but it's actually a freshly instantiated viewcontroller. You'd need to pass the actual parent down through the hierarchy to achieve what you're trying.
You could make it easier on yourself if you gave each cell a "presentationDelegate" of some sort, that would handle all presentation of cards.
I have this NavigationController hat has Large Titles enabled for its NavigationBar. The root ViewController has a SearchController, and hidesSearchBarWhenScrolling is set to True in the ViewController's NavigationItem as I don't want the SearchBar to be always visible. The ViewController has a TableView and when you tap on one of its items a new instance of the same ViewController will be pushed onto the Navigation stack using a storyboard segue. However, when looking at the transition between the current and the new ViewController one can observe that the animation doesn't look right: As soon as the new ViewController is moved in the SearchBar becomes empty, just showing its background. When the new ViewController is finally fully visible, the SearchBar will go away without any animation.
This is how I add the SearchController (nothing fancy here):
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let searchController = UISearchController(searchResultsController: nil)
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = true
}
}
And so it looks like when navigating from "One" to "Two":
UISearchController / UINavigationBar shows broken animation when used within UINavigationController
Is there a way to make this look nicer? Of course, in the new ViewController the SearchBar should not be initially visible, so it has to go away somehow. But I would think that the SearchBar on the old ViewController perhaps should be faded out somehow instead of staying there and then suddenly hiding when the transition to the new ViewController is finished. Hopefully I'm just doing something wrong here...
Thanks and Merry Xmas to all of you,
Peter
Try setting the search controller to nil in the viewWillDissappear method.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationItem.searchController = nil
}
Well, I finally found something very useful that I just couldn't find before asking my question:
Broken UISearchBar animation embedded in NavigationItem
Too bad this is known since iOS 11 and still not fixed.
I have View Controller that accepts text input using an UITextView called "myTextView".
When I segue to myTextView, I use the following:
self.performSegueWithIdentifier("myTextView", sender: self)
myTextView is presented. Then next the keyboard is displayed after viewDidAppear:
override func viewDidAppear(animated: Bool) {
self.myTyping.becomeFirstResponder()
}
Everything animates smoothly. However I want the keyboard to display at the same time as the segue animating and being displayed together and not one after the other.
I can do that with the call for the keyboard with the segue call. However, the animation is jittery and choppy, and not smooth.
How can I both segue to myTextView View Controller and display the keyboard at the same time without any animation jitters?
I have a TableViewController and I would like to trigger a segue within its navigation bar. I created the segue in the storyboard to my new ViewController. However if I click the bar button item, the view does not appear.
Instead the bar button item becomes inactive (greyed out) and the app freezes. There is no error message and the app does also not crash. The prepareForSegue method in my TableViewController also gets called
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
print("prepare for segue called")
print("destination view controller = \(segue.destinationViewController.description)")
}
I did the following things:
created a custom view Controller class for the second screen (in my storyboard and as a .swift file). I assigned the respective ViewController in the storyboard to my custom view controller in the Identity inspector
created an IBAction for a click event on the button and triggered
the segue programatically. The result remains the same.
prepareForSegue is called. The destionationViewController is correct
but does not show up. I removed this IBAction afterwards.
My destination view controller looks like this
class EnterUserDataViewController : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("EnterUserDataViewController viewDidLoad called")
}
}
viewDidLoad never gets called even though the right segue has been triggered.
Can someone please give me a hint on why this happens?
You wouldn't happen to have a rogue breakpoint set somewhere would you?
If I put a breakpoint somewhere in the view loading cycle it recreates the exact symptoms you are describing.
I am trying to make a splash screen. I have a view that has a background image being drawn onto it and then another view I want to transition to after a few seconds. I am trying to use the following code:
self.performSegueWithIdentifier("showApp", sender: self)
I created a segue between the two views by ctrl+dragging a line from one to the other. I set the segue's identifier to "showApp".
When I run the code nothing happens and there are no errors. Any ideas?
Here is the controller for the splash screen:
class SplashViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
sleep(2)
// THIS DOES NOTHING:
self.performSegueWithIdentifier("showApp", sender: self)
// THIS AS SUGGESTED ALSO DOES NOTHING:
var otherViewController:UIViewController = self.storyboard.instantiateViewControllerWithIdentifier("test") as UIViewController
self.presentViewController(otherViewController, animated: true, completion: nil)
}
}
Normally, you need a navigation controller in order to use segue.
Highlight your SplashViewController object inside the Storyboard and go to
Editor -> Embeded In -> Navigation Controller
After that, remove the code suggested by Clement and try running the project again, you should get the result that you expected.