0

我正在使用标准为 SwiftUI 中的顶部导航栏实现渐变背景NavigationView。对于渐变,我使用 aUIGraphicsImageRenderer创建渐变图像,然后将其分配给backgroundImageof UINavigationBarAppearance。到目前为止,在绘制渐变并将其呈现在顶栏上时,一切都正常。

坡度 在此处输入图像描述

但是,我还不能backgroundImage根据视图动态地进行更改。如果您将其粘贴到操场上,下面的完整代码应该可以工作。

import SwiftUI

struct NavBarGradient: ViewModifier {
    
    init(from: UIColor, to: UIColor) {
        let appearance = UINavigationBarAppearance()
        appearance.backgroundColor = .clear
        
        let imageRenderer = UIGraphicsImageRenderer(size: .init(width: 1, height: 1))
        let gradientImage : UIImage = imageRenderer.image { ctx in
            let gradientLayer = CAGradientLayer()
            gradientLayer.frame = imageRenderer.format.bounds
            gradientLayer.colors = [from.cgColor, to.cgColor]
            gradientLayer.locations = [0, 1]
            gradientLayer.startPoint = .init(x: 0.0, y: 0.0)
            gradientLayer.endPoint = .init(x: 0.5, y: 1.0)
            
            gradientLayer.render(in: ctx.cgContext)
        }
        appearance.backgroundImage = gradientImage
        
        UINavigationBar.appearance().standardAppearance = appearance
        UINavigationBar.appearance().compactAppearance = appearance
        UINavigationBar.appearance().scrollEdgeAppearance = appearance
    }
    
    func body(content: Content) -> some View {
        content
    }
    
}

extension View {
    func navBarGradient(from: UIColor = .systemRed, to: UIColor = .systemYellow) -> some View {
        modifier(NavBarGradient(from: from, to: to))
    }
}

struct SimpleView: View {
    var body: some View {
        Text("Gradient View").navigationTitle("Gradient Colors")
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink(
                    "Blue to Cyan",
                    destination: SimpleView()
                        .navBarGradient(from: .systemBlue, to: .systemCyan)
                )
                NavigationLink(
                    "Green to Mint",
                    destination: SimpleView()
                        .navBarGradient(from: .systemGreen, to: .systemMint)
                )
                NavigationLink(
                    "Red to Yellow",
                    destination: SimpleView()
                        .navBarGradient() // comment me out and previous modifier wins
                )
            }
                .navigationTitle("Main Menu")
                .navigationBarTitleDisplayMode(.inline)
        }
    }
}

现在.navBarGradient()视图修饰符似乎是“最后一个获胜”,考虑到视图系统在 SwiftUI 中的工作方式,这是有道理的。所以我想了解的是 - 动态更新外观的“SwiftUI 方式”是什么?

通过调整这样的解决方案,我已经能够在顶部栏中实现渐变背景;它完全按照需要工作。但似乎能够为服务器端图像等动态更新顶栏背景图像将是一件有用的事情。

提前致谢!

4

0 回答 0