UINavigationBar background Image - broken in iOS 11? - uinavigationbar

The following code was working perfectly fine for setting a custom image as the background of a UINavigationBar:
// In AppDelegate.swift:
let image = UIImage(named:"HeaderBanner-new")
UINavigationBar.appearance().setBackgroundImage(image, for: UIBarMetrics.defaultPrompt)
Since switching to Xcode 9, Swift 4, and iOS 11, this code no longer works. All I'm getting is a plain white background in the UINavigationBar.
I also tried moving the code out of the AppDelegate.swift and putting it directly in my root custom UINavgiationController.swift file:
let image = UIImage(named:"HeaderBanner-new")
self.navigationBar.setBackgroundImage(image, for: UIBarMetrics.defaultPrompt)
Still doesn't work.
Any ideas what's going on - or ideas for a workaround/hack?

It seems NavigationBar.setBackgroundImage doesn't work as expected in iOS 11.
I had the same issue and fixed it by using NavigationBar.barTintColor and it worked.
Refer this answer.

Related

How to remove Tab Bar top border (shadow) in > iOS 10 and Swift 4 with a background image?

I've been trying to remove the top border (shadow) line from Tab Bar in Swift 4 for > iOS 10. I'm also using a custom background image. I've just given up after searching for solutions, since none of them work.
The solution which came closest was this post.
The solution given everywhere works if there is no background or for < iOS 10. For iOS > 10 and using a custom background image none of solutions work.
I even tried using a transparent shadow image, but it required setting cliptobounds to true which doesn't show custom background image.
So at the end of all these solution I'm stuck. Couldn't find any working solution.
I'm setting these custom values in AppDelegate so that it works for all Tab Bars.
I just created a sample project using tab bar template from Xcode and write three lines of code
self.tabBar.layer.borderWidth = 0
self.tabBar.clipsToBounds = true
self.tabBar.backgroundColor = .blue
And tab bar top border is no longer visible. I've tested this on Simulator iphone 6 with ios 11.2

Share sheet Cancel buttons invisible swift

Is anyone else running into this problem. I recently noticed that the cancel/save buttons on the share sheets are now white making them impossible to read.
I've tried changing the navigation bar color but that doesn't even seem to work so clearly I'm missing something else.
This still works properly on devices running IOS 10 but having issues with devices running IOS 11
messanger
Mail
Notes
Twitter
I've ran into similar issues. It seems like title text attributes set on UINavigationBar get passed down to the UIActivityViewController from iOS 11 on.
So something like this:
let barButtonItemTextAttributes = ...
let barButtonItemAppearance = UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self])
barButtonItemAppearance.setTitleTextAttributes(barButtonItemTextAttributes, for: UIControlState())
... affects the sharing sheets as well. In my case, the foregroundColor attribute was set to .clear to disable Back button labels on the navigation bar, but it also removed the above mentioned cancel/save buttons.
Maybe this applies to your case as well.

iOS 8: UIButton appearance font

Trying to set UIButton's font for all buttons using appearance in iOS 8. After Googling, it appears that Apple has changed the way you do this from OS to OS. In iOS 7, this should have worked:
UIButton.appearance().titleLabel?.font = UIFont.inviteButtonTitleFont()
But it doesn't seem to work anymore. Anyone know how you do it now?
Swift 3:
let fontRegular = UIFont(name: "MyCustomRegularFont", size: 17.0)
UILabel.appearance(whenContainedInInstancesOf: [UIButton.self]).font = fontRegular
UIButton.appearance().tintColor = UIColor.red
The proxy for font was removed from UILabel.appearance(), so that's the reason why this not works.
Use the appearance when contained in method on UILabel
UILabel.appearanceWhenContainedInInstancesOfClasses([UIButton.self]).font = UIFont.inviteButtonTitleFont()
This should work in iOS9, see this answer appearanceWhenContainedIn in Swift for iOS8 and 7 workarounds.
(Disclaimer, I have not compiled the code snippet so beware of typos).

UINavigationBar appearance background image duplicated and blurred in iOS 7.1

I have an interesting issue with an existing project and iOS7.1, I think. I've had code working and performing normally; since updating XCode and my iOS on my devices I have a problem, a transparent background image used in the Navigation Bar for that project is now rendered twice, once at the correct size and again blown up and blurry. The code only adds the image via the [UINavigationBar appearance] api in the app delegate. To check that this wasn't a specific bug with my code I create a default xcode project using the master detail default, set it to be iPhone only, added some newly created images and set them using the same calls in the app delegate. This project had the same issue and is on github here:
UINavigationBarBug github source
This is the relevant chunk of code imo:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"TLS.png"]
forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBarTintColor:RGB(233, 155, 20)];
[[UINavigationBar appearance] setTintColor:RGB(245, 245, 245)];
return YES;
}
A screenshot of the problem:
Looking at the transition documentation what i am doing here should be fine, the navigation bars at 44 points high should be scaled horizontally and not vertically. I'm also pretty sure this problem never occurred prior to the update (it would have been spotted by internal QA prior to uploading the code to apple for review).
Two things fix it:
1) Using non transparent images, if it still has the problem it is loading the 'correct' image second and due to the lack of transparency overriding the incorrectly rendered one.
2) Using a navigation bar that is 66 points high instead (available in the project with a top transparent section as TLS-ios7), changing the code in the app delegate to use that fixes the problem.
Can anyone enlighten me as to what is going on here? Is this a bug, is it my fault, is there some section of documentation that informs me why this is so?
Thanks!
** Update: I recently found an iPad lying around still running iOS 7.0, this problem does not occur. **
I had a similar issue on my app. I solved it by setting the "translucent" of my UINavigationBar to NO.
[self.navigationController.navigationBar setTranslucent:NO];
You can disable image stretching by defining left and top caps.
Here's a Swift 3 solution:
let navbarImage = image.stretchableImage(withLeftCapWidth: 1, topCapHeight: 1)
UINavigationBar.appearance().setBackgroundImage(navbarImage, for: .default)
Example before:
and after the fix:
I just received this following my bug report... tl;dr It's me providing an image with an incorrect height:
Workaround for iOS 7.1 is to specify a resizable image with a non-zero inset. Internally UINavigationBar will tile your image if it isn't quite the right size and that is basically what was happening here – since the image wasn't tall enough (the navigation bar is top attached, so the image needed to be 64pt tall not 44pt) it would get tiled. If you set it to stretch and configure the cap insets such that it only stretches pixels that are uniform you should be able to avoid this issue.
I had a similar looking issue and it turns out I didn't have the correct image assets in the assets catalog. I only had retina assets but when I imported, they went into the 1x box in the asset catalog - moving them to the 2x box fixed my nav bar for me.
I had a similar problem, I had a logo with transparent background. Height was fine. Added in coloured background and the problem stopped.

setBackgroundImage for UIButton in IOS 7.1 not working

I am trying to change the button background image. This code is working fine with IOS 6/7. After I upgrade to IOS 7.1 suddenly it is stop working.
[monday setBackgroundImage:[UIImage imageNamed:#"toggleTopRight"] forState:UIControlStateNormal];
BWT: the image is ok, because this code is being called in view will appear and this ok there ... when i press on the button that need to change the setBackgroundImage it's not working.
This is a bug on 7.1 SDK and Xcode 5.1.
The workaround is to call [UIButton setNeedsLayout] after your changes.
That should do the trick.
I had the same problem. I finally found out that setting a button's (background) image doesn't work on iOS 7.1, if the button is disabled.
Not sure if this fixes your problem, but it was mine. Calling setNeedsLayout didn't help in my case, unfortunately. What you can do as a workaround is either to override UIButton or to add a category that contains a method like the following to set an image:
- (void)setBackgroundImage:(UIImage *)img forButtonState:(UIControlState)state
BOOL shouldEnable = self.enabled;
self.enabled = YES;
[self setBackgroundImage:img forState:state];
self.enabled = shouldEnable;
}
Filed a bug report for this issue (16497031).
For me it's the foreground image that covered the background image. So make your foreground image transparent then the background image will show. Setting background image actually works fine now.

Resources