0

標準を使用して、SwiftUI のトップ ナビゲーション バーにグラデーションの背景を実装していますNavigationView。グラデーションの場合、 を使用してグラデーション イメージを作成し、それをにUIGraphicsImageRenderer割り当てます。これまでのところ、グラデーションを描画してトップバーにレンダリングするという点で、すべてが正しく動作しています.backgroundImageUINavigationBarAppearance

勾配 ここに画像の説明を入力

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