SwiftUI:为 .toolbar ToolbarItem 设置单独的颜色?

Sun*_*rts 5 swiftui

通常,出于可访问性原因,我喜欢坚持使用默认颜色选项,但我有一个特定的用例,我无法更改单个 .toolbar ToolbarItem 颜色。

我可以通过使用代码段顶部注释掉的代码来覆盖所有ToolbarItem 颜色,但我想为单个图标着色。

import SwiftUI

struct ContentView: View {
    
//    init() {
//        UIBarButtonItem.appearance(whenContainedInInstancesOf: [UIToolbar.self]).tintColor = .systemRed
//    }
    
    var body: some View {
        
        NavigationView {
            
            Text("Hello, world!")
                .toolbar {
                    
                    // To be colored RED
                    ToolbarItem(placement: .bottomBar) {
                        Button(action: {}, label: {Label("Icon One", systemImage: "stop.fill")})
                    }
                    
                    // To be colored BLACK
                    ToolbarItem(placement: .bottomBar) {
                        Button(action: {}, label: {Label("Icon Two", systemImage: "play.fill")})
                    }
                    
                }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

ple*_*his 9

是的,我一直在为同样的事情苦苦挣扎。它看起来Buttons正在使用系统色调颜色及其整体风格。

这是我的看法:

content
    .toolbar {
        ToolbarItem(placement: .navigationBarLeading) {
            HStack {
                StyledButton(image: .system("arrow.left")) { ... }
                Spacer(minLength: 0)    // important to not fell button to default styling
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

这个想法不是只显示 Button,而是与其他 UI 元素一起显示。对我来说看起来像一个 SwiftUI 错误。(或者只是想比你聪明。)


Asp*_*eri 2

看起来所有标准类型(按钮、图像、文本等)都被 ToolbarItem 拦截并转换为适当的内部表示。但自定义视图(例如基于形状)......不是。因此,请参阅下面的可能方法的演示。

使用 Xcode 12 / iOS 14 准备和测试演示。

演示

ToolbarItem(placement: .bottomBar) {
    ShapeButton(shape: Rectangle(), color: .red) {
        print(">> works")
    }
}
Run Code Online (Sandbox Code Playgroud)

和简单的自定义基于形状的按钮

struct ShapeButton<S:Shape>: View {
    var shape: S
    var color: Color
    var action: () -> ()

    @GestureState private var tapped = false
    var body: some View {
        shape
            .fill(color).opacity(tapped ? 0.4 : 1)
            .animation(.linear(duration: 0.15), value: tapped)
            .frame(width: 18, height: 18)
            .gesture(DragGesture(minimumDistance: 0)
                .updating($tapped) { value, state, _ in
                    state = true
                }
                .onEnded { _ in
                    action()
                })
    }
}
Run Code Online (Sandbox Code Playgroud)