I can do translucent UINavigationBar transparent using this code:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationController!.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
navigationController!.navigationBar.shadowImage = UIImage()
}
But if you try this, you'll notice bad effect during push animation transition. Navigation bar becomes transparent immediately, before left screen completely disappears.
But on the other side, if you try this code....
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationController!.setNavigationBarHidden(true: animated: animated)
}
... animation will be perfect: navigation bar disappears only on the right screen, so transition animation looks good.
Is there any way to make UINavigationBar transparent like in the first snippet with animation effect like in the second snippet?
yes, you need to make a method in your code which makes a delay for how many seconds your app is opened for example: [self performSelector:#selector(delay) withObject:nil afterDelay:5.0]; this would make when your app opens, after 5 seconds it will run everything you put in the delay method. So, I would find the second or mess around when you want the UINavigationBar to be transparent and you could easily find the code to make the UINavigationBar transparent but I don't know it off the top of my head.
Related
Overview:
I would like to set the accessibility focus to the navigation bar's title item.
By default the focus is set from top left, meaning the back button would be on focus.
I would like the title item to be in focus.
Attempts made so far:
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification,
navigationController?.navigationBar.items?.last)
Problem:
The above code makes no difference, the back button is still in focus.
Possible Cause:
Not able to get the item corresponding to the title to be able to set the focus.
Solution 1
I don't like it, but it was the minimum amount of hacking that does not rely on digging through hidden subviews (internal implementation of UINavigationBar view hierarchy).
First in viewWillAppear, I store a backup reference of the back button item,
and then remove the back button item (leftBarButtonItem):
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
backButtonBackup = self.navigationItem.leftBarButtonItem
self.navigationItem.leftBarButtonItem = nil
}
Then I restore the back item, but only after I dispatch the screen changed event in viewDidAppear() :
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
self?.navigationItem.leftBarButtonItem = self?.backButtonBackup
}
}
Solution 2:
Disable all accessibility on the nav bar and view controller up until viewDidAppear() is finished:
self.navigationController.navigationBar.accessibilityElementsHidden = true
self.view.accessibilityElementsHidden = true
, and then in viewDidAppear manually dispatching the layout element accessibility focused event to the label subview of UINavigationBar:
UIAccessibilityPostNotification( UIAccessibilityLayoutChangedNotification, self.navigationController.navigationBar.subviews[2].subviews[1])
// The label buried inside the nav bar. Not tested on all iOS versions.
// Alternately you can go digging for the label by checking class types.
// Then use DispatchAsync, to re-enable accessibility on the view and nav bar again...
I'm not a fan of this method either.
DispatchAsync delay in viewDidAppear seems to be needed in any case - and I think both solutions are still horrible.
I invoked UIAccessibilityScreenChangedNotification on navigation title from viewDidLoad and it worked
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification,
self.navigationItem.title);
First, we'll need to create an useful extension:
extension UIViewController {
func setAccessibilityFocus(in view: UIView) {
UIAccessibility.post(notification: .screenChanged, argument: view)
}
}
Then, we'll be able to set our focus in the navigation bar title like this:
setAccessibilityFocus(in: self.navigationController!.navigationBar.subviews[2].subviews[1])
I am using the IQKeyboardManagerSwift latest version I am having issue black screen at bottom --> When I tap on text field in landscape mode of device keyboard comes up and view of controller and background image goes up black screen of window can be seen at bottom View does not come back to original position after keyboard dismiss.
I want to move container view of the text field up, not the view of the controller and background image, the container view is horizontally and vertically center in auto layout. I tried to add IQLayoutGuideConstraint to container view but no luck. it would be great if you can provide some information to achieve it. please seen storyboard screenshot below
try to remove your firstResponder from viewDidLoad, and put it in viewDidAppear instead, like this
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
yourTextField.becomeFirstResponder()
}
P.S. Do not set your textfield as firstResponder in your viewController.
For ex:- (in ViewDidLoad Method)
[self.yourTextField becomeFirstResponder];
If you have above set up. Please comment(Delete) this line and then try.
All the best.
Have you tried to update your pods?
pod IQKeyboardManagerSwift
workround, place in your VC viewillappear:
override func viewWillAppear(_ animated: Bool) {
if let window = (UIApplication.shared.delegate?.window)! as UIWindow? {
window.backgroundColor = UIColor.white
}
}
i have my base View controller with it´s embbed navigation controller so i set ist collor , when segue are executed the new view has it owns navigationbar color and it changes to it but after return to the back view this view takes the color from the previuos one.
i´m setting the color of the navigationbar like this
override func viewDidLoad() {
self.navigationController?.navigationBar.barTintColor = appDelegate.verde
}
its a defined color in the Appdelegate to be green color in the
in the next one i change in the color of the navigationbar the same way as above.
You change the color of the UINavigationBar and it remains changed unless you explicitly change it to something else. UINavigationBar does not depend on viewControllers - it's above them.
In order to have different color for each viewController when navigating between them back and forth, change UINavigationBar's color in viewWillAppear(_ animated: Bool).
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.navigationBar.barTintColor = appDelegate.verde
}
Instead of viewDidLoad you may put this code in viewWillAppear. This will be invoked each time the view is about to be presented so it will override any color changes for other views.
I thought showing a screenshot would help understand the issue a bit better.
So the context is the following:
I'm in a navigation controller, on the settings screen of the app (which has a navigation item) and when we tap on the back button, we go back to the main screen of the app (for which I've hidden the navigation bar in the viewWillAppear of the main screen because I'm building a custom header view myself).
At soon as I tap on the back button, the navigation bar disappears immediately and I see a black rectangle appears instead until the animation to display the main screen is completed.
Do you know how I can avoid having this black rectangle appear?
Hope the questions makes sense.
Screenshots
Here is the initial settings screen:
When we tape on the back button, this happens... help :D
I know this piece of code is most likely responsible for the error, but I absolutely need to have the navigationBar hidden on the previous screen.
override func viewWillAppear(_ animated: Bool) {
navigationController?.isNavigationBarHidden = true
}
Have you tried the animated method of hiding the navigation bar setNavigationBarHidden(_ hidden: Bool, animated: Bool)?
For Swift3.0
Add below code in First ViewController
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
navigationController?.setNavigationBarHidden(true, animated: animated)
}
Add below code in Second ViewController
func backButtonPressed() {
navigationController?.setNavigationBarHidden(false, animated: false)
navigationController?.popViewController(animated: true)
}
Add below code in Second ViewController
the color can corresponding your custom
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.view.backgroundColor = UIColor.white
}
I have an app that has a uipageviewcontroller that is presented on initial launch of the app. On the last page of the uipageviewcontroller I present the main navigation controller with a TransitionCrossDissolve animation.
While the animation is ongoing I get a tiny black background flicker on the right side of the navigation bar like this:
In the beginning I had the black flicker on the whole navigation bar, but after calling
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.layer.removeAllAnimations()
}
the problem almost went away.
Her is a gif of the problem before calling removeAllAnimations():
This i how I call for the animation on the last page of the uipageviewcontroller:
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
UIView.transitionWithView(appDelegate.window!, duration: 0.5, options: UIViewAnimationOptions.TransitionCrossDissolve , animations: { () in
appDelegate.window!.rootViewController = appDelegate.mainNavigationController
}, completion: nil)
It may be important to not that I am using a procedure to remove the hairline at the bottom of the navbar. May this be the reason for all of this?
Ref:
How to hide iOS7 UINavigationBar 1px bottom line
I would greatly appreciate any feedback on the issue.
Brgds
I was able to remove the black UI glitch by removing the animation on all subviews of the navigationbar. I think the problem was with the right UINavigationItem.
Here is the code I used:
let subviews = (self.navigationController?.navigationBar.subviews as [UIView])
for subview: UIView in subviews {
subview.layer.removeAllAnimations()
}