I want to make my navigation bar have a tinge of a colour but not go completely translucent.
Here is the code I have and their results:
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().translucent = true
UINavigationBar.appearance().barTintColor = UIColor(red: 0, green: 107/255, blue: 178/255, alpha: 0.5)
But if I turn the 'translucent' to false i.e use this code:
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().translucent = false
UINavigationBar.appearance().barTintColor = UIColor(red: 0, green: 107/255, blue: 178/255, alpha: 0.5)
I get this result:
How do I make the bar have an alpha value of 0.5 or be 'part translucent'?
Thank you, any help will be appreciated.
I would set a translucent background image for the navigation bar.
Use this code:
UINavigationBar.appearance().setBackgroundImage(UIColor.green.toImage()?.imageWithAlpha(alpha: 0.5), for: .default)
Two extensions used:
Create an UIImage from UIColor:
extension UIColor {
func toImage() -> UIImage? {
return toImageWithSize(size: CGSize(width: 1, height: 1))
}
func toImageWithSize(size: CGSize) -> UIImage? {
UIGraphicsBeginImageContext(size)
if let ctx = UIGraphicsGetCurrentContext() {
let rectangle = CGRect(x: 0, y: 0, width: size.width, height: size.height)
ctx.setFillColor(self.cgColor)
ctx.addRect(rectangle)
ctx.drawPath(using: .fill)
let colorImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return colorImage
} else {
return nil
}
}
}
Create a new UIImage from an UIImage with a specified Alpha:
extension UIImage {
func imageWithAlpha(alpha: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(at: CGPoint.zero, blendMode: .normal, alpha: alpha)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
Related
On iPhone 8 :
On iPhone X :
The issue lies with status bar. The is nothing exclusive I am doing here. It is just that the color is a gradient one, but it should not matter.
ViewController's attributes :
Function for setting gradient :
func setNavigationBarAppearence() {
let gradient = CAGradientLayer()
let sizeLength = UIScreen.main.bounds.size.height * 2
let defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: self.navigationController.navigationBar.frame.size.height)
gradient.frame = defaultNavigationBarFrame
gradient.colors = [UIColor(red: 30/255, green: 234/255, blue: 191/255, alpha: 1).cgColor, UIColor(red: 12/255, green: 198/255, blue: 183/255, alpha: 1).cgColor]
UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)
UINavigationBar.appearance().tintColor = UIColor.white
}
func image(fromLayer layer: CALayer) -> UIImage {
UIGraphicsBeginImageContext(layer.frame.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let outputImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return outputImage!
}
Try this approch. May this solve your problem
/// Applies a background gradient with the given colors
func apply(gradient colors : [CGColor]) {
var frameAndStatusBar: CGRect = self.bounds
frameAndStatusBar.size.height += UIApplication.shared.statusBarFrame.height
let gradient = CAGradientLayer()
gradient.frame = frameAndStatusBar
gradient.colors = colors
// gradient.locations = [0.0,1.0]
gradient.startPoint = CGPoint.init(x: 0.0, y: 0.0)
gradient.endPoint = CGPoint.init(x: 0.0, y: 1.0)
if let img = self.image(fromLayer: gradient)
{
setBackgroundImage(img, for: .default)
}
}
/// Creates a gradient image with the given settings
func image(fromLayer layer: CALayer) -> UIImage? {
UIGraphicsBeginImageContext(layer.frame.size)
if let context = UIGraphicsGetCurrentContext()
{
layer.render(in:context)
let outputImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return outputImage
}
return nil
}
Here is how I used this:
extension CAGradientLayer {
convenience init(frame: CGRect, colors: [UIColor]) {
self.init()
self.frame = frame
self.colors = []
for color in colors {
self.colors?.append(color.cgColor)
}
startPoint = CGPoint(x: 0, y: 0)
endPoint = CGPoint(x: 0, y: 1)
}
func createGradientImage() -> UIImage? {
var image: UIImage? = nil
UIGraphicsBeginImageContext(bounds.size)
if let context = UIGraphicsGetCurrentContext() {
render(in: context)
image = UIGraphicsGetImageFromCurrentImageContext()
}
UIGraphicsEndImageContext()
return image
}
}
extension UINavigationBar {
func setGradientBackground(colors: [UIColor]) {
var updatedFrame = bounds
updatedFrame.size.height += self.frame.origin.y
// above adjustment is important, otherwise the frame is considered without
// the status bar height which in turns causes the gradient layer to be calculated wrong
let gradientLayer = CAGradientLayer(frame: updatedFrame, colors: colors)
setBackgroundImage(gradientLayer.createGradientImage(), for: .default)
}
}
Usage:
override func viewDidLoad() {
...
let colors = [UIColor(red: 30/255, green: 234/255, blue: 191/255, alpha: 1), UIColor(red: 12/255, green: 198/255, blue: 183/255, alpha: 1)]
navigationController?.navigationBar.setGradientBackground(colors: colors)
...
}
This was related to the total height of navigation bar + status bar. I fixed it as follows :
func setNavigationBarAppearence() {
let gradient = CAGradientLayer()
let sizeLength = UIScreen.main.bounds.size.height * 2
var defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: self.navigationController.navigationBar.frame.size.height)
if UIDevice().userInterfaceIdiom == .phone {
if UIScreen.main.nativeBounds.height == 2436{
defaultNavigationBarFrame.size.height += 44
} else {
defaultNavigationBarFrame.size.height += 20
}
}
gradient.frame = defaultNavigationBarFrame
gradient.colors = [UIColor(red: 30/255, green: 234/255, blue: 191/255, alpha: 1).cgColor, UIColor(red: 12/255, green: 198/255, blue: 183/255, alpha: 1).cgColor]
UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)
UINavigationBar.appearance().tintColor = UIColor.white
}
func image(fromLayer layer: CALayer) -> UIImage {
UIGraphicsBeginImageContext(layer.frame.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let outputImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return outputImage!
}
Not the perfect fix I would say, but a working alternative.
I have a problem in making the NavigationBar transparent instead it shows the white as background color.
I wish to achieve this
But instead i am getting the following NavigationBar as background color.
It is showing white as background color. It is not getting transparent
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.view.backgroundColor = UIColor.clear
self.navigationController?.navigationBar.setBackgroundImage(imageWithColor(color: color.withAlphaComponent(alpha)), for: .default)
self.navigationController?.navigationBar.shadowImage = imageWithColor(color: color.withAlphaComponent(alpha))
fileprivate func imageWithColor(color : UIColor) -> UIImage? {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let ctx = UIGraphicsGetCurrentContext()
ctx?.setFillColor(color.cgColor)
ctx?.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
call in func viewWillAppera . you will get
You also try below code.
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default);
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
self.navigationController?.navigationBar.isTranslucent = true
I am trying to use custom color in MFMessageComposeViewController. I thought it will be okay to use:
#IBAction func sendMessage(sender: AnyObject) {
let messageVC = MFMessageComposeViewController()
messageVC.body = "Enter a message";
messageVC.recipients = [phoneString]
messageVC.messageComposeDelegate = self;
//color
UINavigationBar.appearance().barTintColor = UIColor(hexString: "fec13e")
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
self.presentViewController(messageVC, animated: false, completion: nil)
}
but its not working.
You can use the below code to change the color of MFMessageComposeViewController navigation color.
let size = CGSize(width: (self.window?.frame.size.width)!, height: 64)
let image = self.getImageWithColor(UIColor .init(colorLiteralRed: 40.0/255.0, green: 140.0/255.0, blue: 204.0/255.0, alpha: 1.0), size:size)
UINavigationBar.appearance().setBackgroundImage(image.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch), for: .default)
Where getImageWithColor is the func which return image of desired color
func getImageWithColor(_ color: UIColor, size: CGSize) -> UIImage
{
let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: size.width, height: size.height))
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
This is what the project currently looks like
And this is the code that I use
func styleNavBar() {
let navigationBarAppearace = UINavigationBar.appearance()
navigationBarAppearace.tintColor = UIColor(red:1.0, green:1.0, blue:1.0, alpha:1.0)
navigationBarAppearace.titleTextAttributes = [NSForegroundColorAttributeName:UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)]
navigationBarAppearace.translucent = true
navigationBarAppearace.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.3)
navigationBarAppearace.setBackgroundImage(UIImage(), forBarMetrics: .Default)}
I have tried to remove the following code, but then it looks like this.
navigationBarAppearace.setBackgroundImage(UIImage(), forBarMetrics: .Default)
My question is, how do I get the navbar to fill up to the top? and still have the same look
First, create an extension for UIImage which create image with solid color of specified size.
Keep this extension in any ViewController at class label
extension UIImage {
class func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
}
then use the below method to customise your navbar
func styleNavBar() {
let navigationBarAppearace = UINavigationBar.appearance()
navigationBarAppearace.tintColor = UIColor(red:1.0, green:1.0, blue:1.0, alpha:1.0)
navigationBarAppearace.titleTextAttributes = [NSForegroundColorAttributeName:UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)]
navigationBarAppearace.isTranslucent = true
let colorImage = UIImage.imageWithColor(color: UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.3), size: CGSize(width: UIScreen.main.bounds.width, height: 64))
navigationBarAppearace.setBackgroundImage(colorImage, for: .default)
}
Hope this will solve your problem.
I'm using this code on my UINavigationBar to make it transparent. You can adjust it to your needs. In the picture there's a searchController in the titleView
if let topBar = self.navigationController?.navigationBar {
topBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
topBar.shadowImage = UIImage()
topBar.barTintColor = UIColor.clearColor()
topBar.tintColor = UIColor.whiteColor()
topBar.translucent = true
}
Here's what it looks like:
The problem is that color that I set for the UINavigationBar is different from the same color, which I have set for the layer. I want it to be the same! :) (see image)
AppDelegate.swift
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage.imageWithColor(primaryColor), forBarMetrics: .Default)
UINavigationBar.appearance().barTintColor = primaryColor
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName: UIFont.systemFontOfSize(17), NSForegroundColorAttributeName:UIColor.whiteColor()]
MyController.swift in viewDidLoad()
view.backgroundColor = primaryColor
Extensions.swift
let primaryColor = UIColor(red: 132/255, green: 205/255, blue: 93/255, alpha: 1)
extension UIImage {
class func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextFillRect(context, rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
I think the problem is in UIImage extension. Please help me to solve this problem.
Solved
UINavigationBar.appearance().translucent = false
Just uncheck the Translucent property of Navigation Bar. It's worked for me.