如何在 SwiftUI 中删除或隐藏 Toggle 的标签

How to remove or hide the label of a Toggle in SwiftUI

我正在寻找一种方法来删除 SwiftUI 中 Toggle 的标签...

我试过ToggleStyle,但似乎不是正确的方法:

Toggle(isOn: $isBlinky) {
    Text("DO NOT DISPLAY").color(.red)
}
.toggleStyle(.switch)

由于标签似乎包含在类型本身中 (struct Toggle<Label>),因此可能无法仅使用开关...

顺便说一下,如果我使用 Text("") 然后 scaledToFit() 开关仍然有点靠右,并没有真正居中...

无论如何,如果有人有想法!

PS: 在等待解决方案的过程中,我包装了一个很好的旧UISwitch,但是这不是主意...

struct Switch : UIViewRepresentable {
    @Binding var isOn : Bool

    func makeUIView(context: Context) -> UISwitch {
        let uiView = UISwitch()
        uiView.addTarget(
            context.coordinator,
            action: #selector(Coordinator.didChange(sender:)),
            for: .valueChanged)

        return uiView
    }

    func updateUIView(_ uiView: UISwitch, context: Context) {
        uiView.isOn = isOn
    }

    // MARK:- Coordinator

    func makeCoordinator() -> Switch.Coordinator {
        return Coordinator(self)
    }

    class Coordinator: NSObject {
        var control: Switch

        init(_ control: Switch) {
            self.control = control
        }

        @objc func didChange(sender: UISwitch) {
            control.isOn = sender.isOn
        }
    }
}

要自定义 Toggle,您可以自己制作 ToggleStyle

struct CustomToggleStyle: ToggleStyle {

    func body(configuration: Toggle<Self.Label>) -> Text {
        // Define look and feel for the toggle
        Text("Text toggle (?)")
    }

    typealias Body = Text

}

extension StaticMember where Base: ToggleStyle {

    static var custom: CustomToggleStyle.Member {
        return .init(CustomToggleStyle())
    }

}

并像这样使用它

.toggleStyle(.custom)

这似乎是这样做的方式,但是API还没有准备好

configuration 没有公开我们构建切换所需的值。

通过 dumping,我可以看到它有一些有用的属性...

SwiftUI.Toggle<SwiftUI.ToggleStyleLabel>
  - label: SwiftUI.ToggleStyleLabel
  - state: SwiftUI.ToggleState.off
  - setOn: (Function)

...但他们似乎是私人的。

一旦我发现更多,我会更新这个答案。

我不是 "magic numbers" 的忠实粉丝,我倾向于避开它们。经过大量调试(包括 UI 测试视图转储),罪魁祸首是 SwiftUI 对 DefaultToggleStyle() 的实现。该样式的(不存在的)标签实际占用的 space 无法消除,正如我们所见,必须手动调整。但是,如果您创建自定义切换样式,则可以消除对 "adjust" 切换位置的垫片的需要。关键是要从自定义切换样式的视图中完全消除标签。然后,您需要为切换的 "on" 和 "off" 状态创建视图并为转换设置动画。基本上你必须从头开始重新实现 Switch Control。

我更新了下面的示例以展示如何在给定适当图形的情况下实现完美对齐。 Capsule 和 Toggle 确实对齐。否则,唯一的选择就是希望幻数不要经常改变。

顺便说一句,默认样式下的Switch尺寸是57宽31高

import SwiftUI

extension Set {
    subscript(member: Element) -> Bool {
        get {
            return contains(member)
        }
        set {
            if newValue {
                insert(member)
                print("Selecting: \(member)")
            } else {
                remove(member)
                print("Deselecting: \(member)")
            }
        }
    }
}

struct ContentView: View {
    var items:[String] = ["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"]
    @State var selection: Set<String> = Set<String>()
    var body: some View {
        List(self.items, id: \.self) { item in
            VStack {
                Capsule().frame(width: 50, height: 30, alignment: .center)
                HStack {
                    Spacer()
                    Toggle(item, isOn: self.$selection[item])
//                        .frame(width: 25)
//                        .offset(x: -5) // Center toggle
                        .toggleStyle(CustomToggleStyle())
                    Spacer()
                }
            }
        }
    }
}

struct CustomToggleStyle: ToggleStyle {
    public func makeBody(configuration: CustomToggleStyle.Configuration) -> some View {
        HStack {
            if configuration.isOn {
                Button(action: { configuration.isOn.toggle() } )
                { Capsule().frame(width: 50, height: 30).foregroundColor(.red) }
            } else {
                Button(action: { configuration.isOn.toggle() } )
                { Capsule().frame(width: 50, height: 30).foregroundColor(.green) }
            }
//            configuration.label
        }
    }
}

SwiftUI 1.0

使用 labelsHidden 修饰符

隐藏 label/title

应该这样做。

Toggle("Turn alarm on", isOn: $isToggleOn)
    .labelsHidden() // Hides the label/title

注意:即使标签被隐藏,您仍应添加一个以方便访问。

示例:

您可以使用 .labelsHidden() 修饰符隐藏标签:

Toggle(isOn: $switchValue) {}
      .labelsHidden()