I have a UITableViewControllerthat presents a UIViewController modally when didSelectRowAtis invoked.
My application is wrapped in a UITabBarController.
I would like to dismiss the UIViewController when a user changes tabs.
I have tried to call dismiss on my controller like so, but this does not work.
let vc = VimeoController()
....
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
vc.dismiss(animated: true) {
print("dismissed")
}
}
...
fileprivate func presentModal() -> Void {
vc.modalPresentationStyle = .overCurrentContext
present(vc, animated: true, completion: nil)
}
Place your dismiss call within the viewDidDisappear lifecycle hook of your VimeoController controller instead.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
dismiss(animated: true, completion: nil)
}
I am trying to fade-in a background gradient image and slide up a uiview card from the bottom (off-screen) to the center of the uiviewcontroller - executing both animations simultaneously when the uiviewcontroller is presented modally.
What I've attempted is to set the uiviewcontroller modal transition style to cross dissolve, which would provide the fade-in effect for the background gradient image, and in viewDidAppear run the animation to slide up the uiview card from the bottom to center.
While this works, there's a slight delay with the card, and ideally I hoped both animations took place at the same time.
Is this grouping possible? Any guidance would be appreciated.
Below is relevant code in the modally presented view controller:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
alertViewCenterYConstraint.constant += view.bounds.height
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 0.1, delay: 0, options: .curveEaseOut, animations: {
self.alertViewCenterYConstraint.constant = 0
self.view.layoutIfNeeded()
}, completion: nil)
}
This one works like a magic. I love it.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
alertViewCenterYConstraint.constant += view.bounds.height
DispatchQueue.main.async {
UIView.animate(withDuration: 0.1, delay: 0.05, options: .curveEaseOut, animations: {
self.alertViewCenterYConstraint.constant = 0
self.view.layoutIfNeeded()
}, completion: nil)
}
}
I have a tap gesture recognizer added on the imageView, so when user taps on the image below function is called.
#objc func handleTap(_ sender: UITapGestureRecognizer) {
self.navigationController?.popViewController(animated: true)
}
When I am pushing to detail view controller animation looks fine and works smooth, but when I am using the above method to popViewController(animated: true) animation is not so smooth and might even freeze for a second.
I am also using viewWillAppear and viewWillDisappear methods to hide navigation bar in detail view controller. I have read that this could cause animation to work slow, but still could not manage to find answer how to solve this.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.isNavigationBarHidden = true
}
override func viewDidDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.isNavigationBarHidden = false
}
Try this, I am not sure but it may work
DispatchQueue.main.async {
self.navigationController?.popViewController(animated: true)
}
In your override of viewDidDisappear(_ animated: Bool) you call super.viewWillAppear(animated). As you have probably figured out by now, you should be calling super.viewDidDisappear(animated) instead. Your corrected code should read:
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
navigationController?.isNavigationBarHidden = false
}
I have a UIViewController VC1 that contains a UIImageView loadingImg. When you segue from a previous UIViewController VC0, it animates. Here is some code from VC1:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
animate()
}
func animate() {
UIView.animate(withDuration: 1, delay: 0, options: [.repeat, .curveLinear], animations: {
self.loadingImg.transform = CGAffineTransform(rotationAngle: .pi / 2)
}, completion: nil)
}
I also have a tabbar, where VC0 is one of the root view controllers. Once VC0 has segued to VC1, when you click on to another root view controller and then back, loadingImg is no longer animating. How can I keep loadingImg animating even if I'm using tabbar to switch to different view controllers and back?
You need to set original position of UIView when you switch UIViewController in ViewDidAppear like below
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.loadingImg.transform = .identity
self.view.layoutIfNeeded()
}
How can I hide a navigation bar from first ViewController or a particular ViewController in swift?
I used the following code in viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
}
and also on viewWillAppear:
override func viewWillAppear(animated: Bool) {
self.navigationController?.isNavigationBarHidden = true
}
Both methods hide the navigation controller from all ViewControllers.
If you know that all other views should have the bar visible, you could use viewWillDisappear to set it to visible again.
In Swift:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)
}
Swift 3
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Hide the navigation bar on the this view controller
self.navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Show the navigation bar on other view controllers
self.navigationController?.setNavigationBarHidden(false, animated: animated)
}
You can unhide navigationController in viewWillDisappear
override func viewWillDisappear(animated: Bool)
{
super.viewWillDisappear(animated)
self.navigationController?.isNavigationBarHidden = false
}
Swift 3
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: animated)
}
You could also create an extension for this so you will be able to reuse the extension without implementing this again and again in every view controller.
import UIKit
extension UIViewController {
func hideNavigationBar(animated: Bool){
// Hide the navigation bar on the this view controller
self.navigationController?.setNavigationBarHidden(true, animated: animated)
}
func showNavigationBar(animated: Bool) {
// Show the navigation bar on other view controllers
self.navigationController?.setNavigationBarHidden(false, animated: animated)
}
}
So you can use the extension methods as below
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
hideNavigationBar(animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
showNavigationBar(animated: animated)
}
In Swift 3, you can use isNavigationBarHidden Property also to show or hide navigation bar
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Hide the navigation bar for current view controller
self.navigationController?.isNavigationBarHidden = true;
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Show the navigation bar on other view controllers
self.navigationController?.isNavigationBarHidden = false;
}
Ways to hide Navigation Bar in Swift:
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.navigationController?.navigationBar.isHidden = true
self.navigationController?.isNavigationBarHidden = true
Ways to show Navigation Bar in Swift:
self.navigationController?.setNavigationBarHidden(false, animated: true)
self.navigationController?.navigationBar.isHidden = false
self.navigationController?.isNavigationBarHidden = false
private func setupView() {
view.backgroundColor = .white
navigationController?.setNavigationBarHidden(true, animated: false)
}
Alternative
in viewDidLoad use this settings
title = "Madman"
navigationController?.isNavigationBarHidden = false
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
Check the constraints of Collectionview, scrollview or tableView
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
Want to Hide the NavigationBar on the First ViewController
override func viewWillAppear(animated: Bool) {
self.navigationController?.isNavigationBarHidden = true
}
Want to Show the NavigationBar on the Second ViewController
override func viewWillAppear(animated: Bool) {
self.navigationController?.isNavigationBarHidden = false
}
/*. Swift 5 */
let controller = self.storyboard?.instantiateViewController(withIdentifier: "sc_userNavigation") as! UserNavigationViewController
let navigationController = UINavigationController(rootViewController: controller)
navigationController.setNavigationBarHidden(true, animated: false)
navigationController.modalPresentationStyle = .fullScreen
self.present(navigationController, animated: false, completion: nil)
In IOS 8 do it like
navigationController?.hidesBarsOnTap = true
but only when it's part of a UINavigationController
make it false when you want it back
I use a variant of the above, and isolate sections of my app to be embedded in differing NavControllers. This way, i don't have to reset visibility. Very useful in startup sequences, for example.
Call the set hide method in view Will appear and Disappear. if you will not call the method in view will disappear with status false.It will hide the navigation bar in complete navigation hierarchy
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.setNavigationBarHidden(false, animated:true)
}
You can do it from the window controller (Swift3)
class WindowController: NSWindowController {
override func windowDidLoad() {
super.windowDidLoad()
window?.titleVisibility = .hidden
}
}