Upon launching my app, I set am "hiding" the tab bar with:
UITabBar.appearance().alpha = 0.0
This is done because some logic is done in order to decide what to display upon launch. It all works, yay! BUT (oh, Stackoverflow time) when the user is all done screwing around with what I have showed them, it is time for the tab bar to reappear. So in a completion block I have (obviously):
UITabBar.appearance().alpha = 1.0
Voila! WAIT NO! Ok so, dispatch_async(dispatch_get_main_queue())? Any luck? NO
Ok fine fine, so let's do a self.view.layoutIfNeeded(). That should do it, right? BONK, NO!
So what's even stranger? Well, when I open a modal on top of this view (with the tab bar still displaying at alpha 0.0 but the code already instructed it to be 1.0 at this point) and then close it, when the view reappears, the tab bar gets redrawn (I assume) and appears with the alpha at 1.0 and showing with all its glory.
So, what gives? And how can I allow the bar to show after the initial state has been drawn to the screen and alpha updated?
Help!
I came across this issue not too long ago, except in the context of the navigation bar. I was curious as well if there exists some sort of means to have the navigation bar redrawn on command. What I observed is if you slid your finger as to move the new page (even slightly), the correct default would appear. Therefore, I concluded this is an issue with redraw not taking place until some sort of interaction occurs. Unfortunately, it seems as though it isn't possible to have this done programmatically.
However, here's the solution I was able to garner that is related your problem:
[Swift 3]
Rather, than using navigationItem.titleView?.tintColor = UIColor.white,
I used:
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white, NSFontAttributeName: UIFont(name: "Copperplate", size: 24.0)]
However, I'm not sure what the correlate is with the tab bar for your scenario. Perhaps, you could figure that out. (I post all of this for those who had my issue and to explain where your issue likely lies).
Now, for your situation. I believe that setting alpha to 0 is likely not the greatest way to approach your problem in the first place.
Give this a try:
UITabBar.appearance().isHidden = true
Hope my solution works or this leads you in the right direction.
Related
The buttons are still there and function fine, however as you can see they are completely invisible. Adjusting font colors and navigation bar colors had no effect. I have been trying to resolve this for months and despite reading Apple's documentation, I am unable to even see where you would change what I assumed to be a system wide function.
So to help narrow down this issue I created a simple navigation controller with a print button. If I put these both on the Login storyboard (the first storyboard) it works perfectly fine. If I put it on Main.storyboard (the second storyboard) it doesn't work.
If I change my project settings to make Main.storyboard the first storyboard it works. Leading me to believe the issue is in my FirstViewController.
You can set the color of the print and cancel button
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UIToolbar.self]).tintColor = UIColor.green
After narrowing down the problem to the first view controller I discovered the tint was set to Clear Color (ie Alpha is 0). Fixing this resolved the problem in the rest of the app. I am surprised a setting in a view can propogate to the rest of the app and overwrite all of the other views in the process. Perhaps apple set the first view to determine the colors for system pop ups etc.
Thanks for taking the time to read.
Firstly, let me say that I have tried to do my due diligence in searching for a solution to the problem, but to no avail, and it is stressing me out! So, if someone finds an answer could you please point me in the direction :)
The problem I am facing is to do with the black line appearing underneath the Navigation Bar. Now, I am very much aware of the setting a default image/shadow image property of the navigation bar to correct this, and as such, I created my own extension to implement it (shown below)
func hideHairline(_ state:Bool) {
if state {
self.shadowImage = UIImage()
self.setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
}else{
self.setBackgroundImage(UINavigationBar.appearance().backgroundImage(for: UIBarMetrics.default), for:UIBarMetrics.default)
self.shadowImage = nil
}
}
However, something seems to be misbehaving, and I am getting a black line appearing underneath my navigation bar (see below)
Whats more strange, is that the simulator does not show this line on the same screen. The simulator is set to be pixel accurate. (as shown below)
I think it may have something to do with the way I am changing from a previous VC. I am changing from having the navigation bar hidden, to shown, and it is set to prefersLargeTitles. Now, if I set the navigation bar, not to use the large titles, the black line doesn't show. Also, if I push to the next view controller, and then pop back, the line is not there (on the pushed controller, or the newly presented popped)
At this point, I am mainly just wondering why this is happening? I mean, I must have done something wrong. I wrote a setup extension, just to keep the code away from the VC, probably isn't the best coding practice, but hey!
self.hideHairline(true)
self.titleTextAttributes = [NSAttributedStringKey.foregroundColor : Constants.navigationBarTextColor]
self.largeTitleTextAttributes = self.titleTextAttributes
self.barTintColor = Constants.navigationBar
self.tintColor = Constants.navigationBarTint
self.isTranslucent = false
self.backgroundColor = Constants.navigationBar
self.prefersLargeTitles = true
The Constants is a class that holds all of the static variables in my app, such as colo(u)rs. Have I just made some stupid mistake, or is there a bug with large titles?
If you need any further information, please, just ask :)
Thanks
So, after taking a break for the evening, I have found a solution. I am going to leave this post up, for anyone else that might encounter a similar problem in the future.
It is to do with the view of the UINavigationController itself. I found another stack overflow post that answered it (link here)
All I had to do was:
self.navigationController?.view.backgroundColor = .white
change the colo(u)r to whatever you need it to be.
Simple solution, and I cannot believe it took me so long to figure out.
All the best.
Built-in Photo application fades in/out navigationBar when you tap on an image . This way Photo app allows to see it full screen.
How does it do this (fade efect)?
As I understand navigationController?.navigationBar.alpha doesn't work anymore (so you can't animate it this way).
Sharing all my finding.
Complain mode on
Frankly, I feel half pissed/like a dummy that I had to fight a good day to implement simple thing existing in Apple app.
Complain mode off
First of all here is some context. I am working with navigationBar which are provided by navigationController (vs just standalone bars which are manually dropped in your view)
There are several approaches which I found. I will mention all of them (even if I had no success using them)
1) Animate change of alpha of navigationBar
UIView.animateWithDuration(0.1, animations: {
navigationController?.navigationBar.alpha = 0
}, completion: nil)
#rmaddy mention here that it works for him. However, I believe he has a standalone bar (vs a bar managed by navigationController).
I used a tool Reveal to check UI hierarchy and found couple of things.
- There is a navigationBar which is hidden (and navigationController?.navigationBar is referencing it). So you can change alpha to your hearts joy, but these changes won't be visible.
There is however another navigationBar . I assume it's referenced in some private members of navigationController (let's call it private navigationBar). It's visible and that's what is displayed at the top of your view.
2) Use setNavigationBarHidden:animated:
This is a standard way to hide/show navigation bar. It's animated different way (it slides/up and down). However, if it's ok for you, just go with this is, because it's simple and clean.
navigationController?.setNavigationBarHidden(true, animated: true)
Additionally you can wrap it in UIView.beginAnimations, UIView.commitAnimations to animate it together with some other stuff (to make it smoother)
3) Animate change of alpha of private navigation bar.
This worked for me:
let privateNavigationBar = self.superview?.superview?.superview?.superview?.superview?.superview?.subviews[1]
UIView.animateWithDuration(0.1, animations: {
privateNavigationBar.alpha = 0
}, completion: nil)
I am going way up through the hierarchy to get a view which contains private navigationBar (which is second subview for that view).
However, this approach has multiple downsides:
I believe # of superviews? depends on your app hierarchy (vs you are using split view and so on). I think you can generalize or may be you just walk the whole hierarchy to find non hidden UINavigationBar to solve this.
I have a feeling that Apple may frown at this (your app be not accepted to AppStore)
4) Make navigationBar transparent and set background image to be transparent and change alpha channel on it.
I can't find where I read about this idea. There was couple of mentioning.
There is Apple example app which shows how to customize NavigationBar, including making it transparent.
It's interesting that this example app works for me (the navigation bar is transparent in it). However, when I tried this code in my app it didn't work (I still didn't figured out what is going on with this). As usual there are bunch of variables (may be something in Info.plist, also they subclass NavigationController, also may be something in view hierarchy)
5) Adding standalone navigationBar
You can hide a bar provided by navigationController. Add your own to the UIView, wire it to #IBOutlet and use alpha animation on it (most likely that's what #rmaddy was referring too).
I checked and this is work.
This approach is used in this tutorial.
However, it has a downside:
I believe it won't handle well rotation, increase of statusbar height while call or GPS
Each time when I see a code like this (written in the article) I know that there will be problems with resizing: CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 64.0)
You can potentially replace it with constrains. I went this route, but stumble upon some issues.
6) Other methods
I saw two more methods. I don't know whether they will work or what will be downsides:
One of them in this question: How to hide/show status bar and navigation bar by fading in/out at the same time like the Photos app in iOS 7?
And this answer: https://stackoverflow.com/a/18063898/422080
I'm currently building an iOS Application for a client and have hit a pretty huge roadblock. I mean, I could write my own UINavigationBar and such but that would cause a lot of issues further down the road.
I have tried everything in my knowledge so far and have spent several hours searching for a solution (overriding the CALayer, using CoreGraphics and pretty much everything else ) and I get the same result. No matter how hard I try to remove the background of the UINavigationBar, it still shows a white background with slight translucency.
I need to have a lot of customisation on the navigation bar (I.E having a gradient going from "blackColor" to "clearColor" and I can't do that if the background of the Navigation Bar refuses to be completely transparent. I have tried copying all of the CALayers from the UINavigationBar layer to a subview I added and it just kept crashing, even when replacing the delegates and superlayer.
I really need help with this. One of the multiple effects I'm trying to achieve are below. (The blue rectangle is not the focus of the image, it's irrelevant.)
To get it completely transparent:
(UINavigationBar.appearance()).translucent = true
(UINavigationBar.appearance()).barTintColor = UIColor.clearColor()
(UINavigationBar.appearance()).backgroundColor = UIColor.clearColor()
(UINavigationBar.appearance()).setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
(UINavigationBar.appearance()).shadowImage = UIImage()
EDIT:
Using iOS 8.3 looking like this:
Or am I missing something?
You are referring to the top Navbar with the back button and Save button right? I'm just confused as to what the blue box on the image is in reference too.
Anyways, this is an extremely hacky approach but could work:
Set the UINavigationBar's alpha to 0. The Back button and Save button will probably also disappear but you could just add labels to the View Controller at the top in the exact same place. The button's should still be functional even though they are "invisible" but the user will still think they are touching them.
Again, very hacky, but you are free to play with the top part of the View then. I'm sure there's a better way to do this but I'm not near a computer with XCode at the moment and can't test it out, and this fix may not even work but I thought I'd offer up a possible temporary solution.
I have a few simple UIBarButtonsItems(no customization other than changing style, color and alpha). Everything was working perfectly fine for some time. But now I need to press BarButton for a long time(4-5 seconds) before the action is triggered. I just moved toolbar around and changed color and alpha after which this started happening. I don't exactly understand what caused this change of behavior.
I used interface builder to build the view and assigned action to UIBarButtonItems by Ctrl+Dragging.
I tried looking up a lot both on google and so. Most of the questions are about UIBarButtons not responding at all. Still I tried the solution of cleaning build of project and Xcode cache. But nothing changed.
Could someone help me with this?
I realized my mistake. I had two events getting triggered in same space in view. First was to reveal toolbar(i.e. increase its alpha) when tapped in particular area of the view and second one was of course button tap event for UIBarButtonItem. When tapped in that area the first event got triggered and eventually when pressed for long it also fired the second event once the toolbar was visible(if toolbar was invisible before).
Sorry to bother you all.