【问题标题】:Show line / separator view in SwiftUI在 SwiftUI 中显示行/分隔符视图
【发布时间】:2019-10-30 07:45:27
【问题描述】:

我想在我的 SwiftUI 应用中显示分隔线。为此,我尝试创建一个带有固定框架和背景颜色/边框的空视图:

EmptyView()
    .frame(width: 200, height: 2)
    .background(Color.black) // or:
    .border(Color.black, width: 2)

很遗憾,我看不到任何暗视图。
有没有办法显示分隔符/行视图?

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    使用Divider:

    可用于分隔其他内容的视觉元素。

    例子:

    struct ContentView : View {
        var body: some View {
            VStack {
                Text("Hello World")
                Divider()
                Text("Hello Another World")
            }
        }
    }
    

    输出:

    【讨论】:

    • 啊!我试过SeparatorLine,但没想到Divider。谢谢!
    • 你如何摆脱这条线上下的神秘填充?
    • @coolcool1994 将 VStack 的 spacing 设置为零。 IE。 VStack(spacing: 0) {…}
    【解决方案2】:

    如果有人对分隔线、文本、分隔线感兴趣,看起来像这样:

    LabelledDivider代码

    struct LabelledDivider: View {
    
        let label: String
        let horizontalPadding: CGFloat
        let color: Color
    
        init(label: String, horizontalPadding: CGFloat = 20, color: Color = .gray) {
            self.label = label
            self.horizontalPadding = horizontalPadding
            self.color = color
        }
    
        var body: some View {
            HStack {
                line
                Text(label).foregroundColor(color)
                line
            }
        }
    
        var line: some View {
            VStack { Divider().background(color) }.padding(horizontalPadding)
        }
    }
    

    这有点难看,但我不得不将Dividers 放入VStack 以使它们水平,否则,由于HStack,它们将是垂直的。如果您设法简化了这一点,请告诉我:)

    另外,LabelledDivider 的使用和存储属性可能不是最有效的SwiftUI-y 解决方案,所以我愿意改进。

    使用示例

    这是导致上面截图的代码:

    struct GetStartedView: View {
        var body: some View {
            NavigationView {
                VStack {
    
                    NavigationLink(destination: SignInView()) {
                        Text("Sign In").buttonStyleEmerald()
                    }
    
                    LabelledDivider(label: "or")
    
                    NavigationLink(destination: SignUpView()) {
                        Text("Sign up").buttonStyleSaphire()
                    }
    
                }.padding(20)
            }
        }
    }
    

    按钮样式

    为了完整起见,我还包括buttonStyle 视图修饰符:

    struct ButtonStyle: ViewModifier {
    
        private let color: Color
        private let enabled: () -> Bool
        init(color: Color, enabled: @escaping () -> Bool = { true }) {
            self.color = color
            self.enabled = enabled
        }
    
        dynamic func body(content: Content) -> some View {
            content
                .padding()
                .frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
                .foregroundColor(Color.white)
                .background(enabled() ? color : Color.black)
                .cornerRadius(5)
        }
    }
    
    extension View {
        dynamic func buttonStyleEmerald(enabled: @escaping () -> Bool = { true }) -> some View {
            ModifiedContent(content: self, modifier: ButtonStyle(color: Color.emerald, enabled: enabled))
        }
    
        dynamic func buttonStyleSaphire(enabled: @escaping () -> Bool = { true }) -> some View {
            ModifiedContent(content: self, modifier: ButtonStyle(color: Color.saphire, enabled: enabled))
        }
    
    }
    
    

    编辑:请注意Color.saphireColor.emerald 是自定义声明的颜色:

    extension Color {
        static var emerald:     Color { .rgb(036, 180, 126) }
        static var forest:      Color { .rgb(062, 207, 142) }
    }
    
    extension Color {
        static func rgb(_ red: UInt8, _ green: UInt8, _ blue: UInt8) -> Color {
            func value(_ raw: UInt8) -> Double {
                return Double(raw)/Double(255)
            }
            return Color(
                red: value(red),
                green: value(green),
                blue: value(blue)
            )
        }
    }
    

    【讨论】:

    • 什么是Color.Radix.emerald
    • 只是我声明的一些颜色...随意替换为您自己的颜色:)
    • @Sajjon 我知道这已经很晚了,但是您可以删除 init 并在视图构造函数中定义标签,就像您使用 init 时一样。只是去除了一层复杂性。
    • 我使用与此非常相似的代码,并且必须添加 .lineLimit(1).fixedSize() 以防止换行符和省略号以实现更长的翻译
    【解决方案3】:

    你可以用颜色画一条线。如果你想改变线宽或填充,你可以像其他 SwiftUI 组件一样使用framepadding

    //Horizontal Line in VStack
    VStack{
        Color.gray.frame(height:CGFloat(1) / UIScreen.main.scale)
    }
    //Vertical Line in HStack
    HStack{
        Color.gray.frame(width:CGFloat(1) / UIScreen.main.scale)
    }
    

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
    • 不错的提示。我从来不知道根据颜色创建框架。谢谢
    【解决方案4】:

    如果您正在寻找自定义分隔线的方法,则没有。您必须提供您的自定义实现:

    struct CustomDivider: View {
        let height: CGFloat = 1
        let color: Color = .white
        let opacity: Double = 0.2
        
        var body: some View {
            Group {
                Rectangle()
            }
            .frame(height: height)
            .foregroundColor(color)
            .opacity(opacity)
        }
    }
    

    【讨论】:

    • 解决方案效果很好,但为什么在这里使用 Group 呢?没有它似乎也能工作
    猜你喜欢
    • 2022-01-02
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 2020-07-14
    相关资源
    最近更新 更多