我正在使用标准为 SwiftUI 中的顶部导航栏实现渐变背景NavigationView
。对于渐变,我使用 aUIGraphicsImageRenderer
创建渐变图像,然后将其分配给backgroundImage
of 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 方式”是什么?
通过调整这样的解决方案,我已经能够在顶部栏中实现渐变背景;它完全按照需要工作。但似乎能够为服务器端图像等动态更新顶栏背景图像将是一件有用的事情。
提前致谢!