How to set shadow radius in UINavigationBarAppearance?

Viewed 197

I am trying to set the shadow radius, but UINavigationBar Appearance doesn't have such a method, there is only the shadowImage method, which doesn't solve the problem.

I need to make a shadow at the NavigationBar so that it is slightly more noticeable. I was able to set its color, but not its radius. How can I do this?

The code itself:

struct ContentView: View {
    
    init() {
        let coloredAppearance = UINavigationBarAppearance()
        coloredAppearance.configureWithOpaqueBackground()
        coloredAppearance.shadowColor = .brown
        coloredAppearance.backgroundColor = .green
        coloredAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.black]
               
        UINavigationBar.appearance().standardAppearance = coloredAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
    }
    
    
    var body: some View {
            NavigationView {
                Text("Screen")
                .navigationBarTitle("Test", displayMode: .large)
                }
            .navigationViewStyle(StackNavigationViewStyle())
            }
}

Result: enter image description here

As we can see, the shadow has a color, but the shadow itself is too small.

2 Answers

On some of my apps I use a custom shadow image, don't know if it will work. Try increasing the height value when creating the shadow image

let shadowImage = UIColor(hexString: "#000000")
            .image(CGSize(width: 1, height: 1 / UIScreen.main.scale))

let coloredAppearance = UINavigationBarAppearance()
coloredAppearance.shadowImage = shadowImage

UINavigationBar.appearance().standardAppearance = coloredAppearance
UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance

@Luch, Thanks for the tip. I also had to torment myself with extensions for this code. This is what the final working code looks like:

    struct ContentView1: View {
    
    init() {
        let shadowColor = UIColor.init(hex: "#000000")
        let shadowImage = UIImage(color: shadowColor, size: CGSize(width: 1, height: 9 / UIScreen.main.scale))
        let alphaImage = shadowImage?.withAlpha(0.5)
        
        let coloredAppearance = UINavigationBarAppearance()
        coloredAppearance.backgroundColor = .green
        coloredAppearance.shadowImage = alphaImage
        coloredAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.black]

        UINavigationBar.appearance().standardAppearance = coloredAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
    }
    
    
    var body: some View {
            NavigationView {
                Text("Screen")
                .navigationBarTitle("Test", displayMode: .large)
                }
            .navigationViewStyle(StackNavigationViewStyle())
            }
}

struct StackOver_Previews: PreviewProvider {
    static var previews: some View {
        ContentView1()
    }
}

// create UIcolor by hex
extension UIColor {
    public convenience init(hex:String) {
        var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
        
        if (cString.hasPrefix("#")) {
            cString.remove(at: cString.startIndex)
        }
        var r: CGFloat = 0.0
        var g: CGFloat = 0.0
        var b: CGFloat = 0.0
        var a: CGFloat = 1.0
        
        var rgbValue:UInt64 = 0
        Scanner(string: cString).scanHexInt64(&rgbValue)
        
        if ((cString.count) == 8) {
            r = CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0
            g =  CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0
            b = CGFloat((rgbValue & 0x0000FF)) / 255.0
            a = CGFloat((rgbValue & 0xFF000000)  >> 24) / 255.0
            
        }else if ((cString.count) == 6){
            r = CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0
            g =  CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0
            b = CGFloat((rgbValue & 0x0000FF)) / 255.0
            a =  CGFloat(1.0)
        }
        
        
        self.init(  red: r,
                    green: g,
                    blue: b,
                    alpha: a
        )
    } }

// create image by Color
public extension UIImage {
    convenience init?(color: UIColor, size: CGSize) {
        let rect = CGRect(origin: .zero, size: size)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        color.setFill()
        UIRectFill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        guard let cgImage = image?.cgImage else { return nil }
        self.init(cgImage: cgImage)
    }
}

// just for setting alpha
extension UIImage {
    
    func withAlpha(_ alpha: CGFloat) -> UIImage {
        return UIGraphicsImageRenderer(size: size).image { _ in
            draw(at: .zero, blendMode: .normal, alpha: alpha)
        }
    }
}

Result: enter image description here

Related