如何在TextField(SwiftUI)上添加底线

Sha*_*aek 3 textfield swift swiftui

我曾经Rectangle()在TextField(SwiftUI)上添加底部边框

但是我想使用protocol TextFieldStyle诸如RoundedBorderTextFieldStyle之类的TextField Style的底线

如何在不使用Rectangle的情况下为TextField创建自定义样式?

https://developer.apple.com/documentation/swiftui/staticmember

在此处输入图片说明

struct ContentView : View {
    @State private var username = "Text Hellow"
    var body: some View {
        VStack() {
            TextField($username)
                .foregroundColor(Color.yellow)
            Rectangle()
                .frame(height: 1.0, alignment: .bottom)
                .relativeWidth(1)
                .foregroundColor(Color.red)

        }
        .padding()
    }

    func editChanged() {

    }
}

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

Har*_*nda 28

分隔线

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

您可以设置colorheight

Divider()
 .frame(height: 1)
 .padding(.horizontal, 30)
 .background(Color.red)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

struct LoginField: View {

    @State private var email: String = ""
    @State private var password: String = ""

    var body: some View {
        VStack {
            TextField("Email", text: $email)
                .padding(.horizontal, 30).padding(.top, 20)
            Divider()
                .padding(.horizontal, 30)
            TextField("Password", text: $password)
                .padding(.horizontal, 30).padding(.top, 20)
            Divider()
                .padding(.horizontal, 30)
            Spacer()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


iGh*_*ost 15

使用 .overlay

TextField("mail@example.com", text: $email)
        .overlay(VStack{Divider().offset(x: 0, y: 15)})
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

的用途VStack是确保Divider始终是水平的。

  • 简直太棒了。最佳答案。 (4认同)
  • 为什么不只使用 .overlay(Divider(),alignment: .bottom)` (3认同)

Sch*_*ken 9

但是,kontiki 的解决方案不适用于Beta 6。所以我创建了一个解决方案,我在新视图中嵌入了一个 TextField 和一个绘制的底线。您可以复制代码并通过TextFieldWithBottomLine(placeholder: "My placeholder")在如下所示的视图中编写Used 来使用它:

TextView 与底线的使用

我创建的第一件事是一条水平线:

import SwiftUI

struct HorizontalLineShape: Shape {

    func path(in rect: CGRect) -> Path {

        let fill = CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height)
        var path = Path()
        path.addRoundedRect(in: fill, cornerSize: CGSize(width: 2, height: 2))

        return path
    }
}

struct HorizontalLine: View {
    private var color: Color? = nil
    private var height: CGFloat = 1.0

    init(color: Color, height: CGFloat = 1.0) {
        self.color = color
        self.height = height
    }

    var body: some View {
        HorizontalLineShape().fill(self.color!).frame(minWidth: 0, maxWidth: .infinity, minHeight: height, maxHeight: height)
    }
}

struct HorizontalLine_Previews: PreviewProvider {
    static var previews: some View {
        HorizontalLine(color: .black)
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来,我创建一个包含 TextField 和下面的 Horizo​​ntalLine 的视图:

import SwiftUI

struct TextFieldWithBottomLine: View {
    @State var text: String = ""
    private var placeholder = ""
    private let lineThickness = CGFloat(2.0)

    init(placeholder: String) {
        self.placeholder = placeholder
    }

    var body: some View {
        VStack {
         TextField(placeholder, text: $text)
            HorizontalLine(color: .black)
        }.padding(.bottom, lineThickness)
    }
}

struct TextFieldWithBottomLine_Previews: PreviewProvider {
    static var previews: some View {
        TextFieldWithBottomLine(placeholder: "My placeholder")
    }
}
Run Code Online (Sandbox Code Playgroud)

为了查看它的实际效果,我创建了一个示例视图:

import SwiftUI

struct SampleView: View {
    @State var text: String = ""
    @ObservedObject var model: LoginModel

    init() {
        self.model = LoginModel()
    }

    init(model: LoginModel) {
        self.model = model
    }

    var body: some View {
        TextFieldWithBottomLine(placeholder: "My placeholder").padding(24)
    }

    func initialActions() {

    }

    func reactOnButtonClick() {

    }
}

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


小智 7

符合 TextFieldStyle 协议

struct BottomLineTextFieldStyle: TextFieldStyle {
    func _body(configuration: TextField<Self._Label>) -> some View {
        VStack() {
            configuration
            Rectangle()
                .frame(height: 0.5, alignment: .bottom)
                .foregroundColor(Color.secondary)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

TextField("Name", text: $presenter.name).textFieldStyle(BottomLineTextFieldStyle())
Run Code Online (Sandbox Code Playgroud)


kon*_*iki 6

要定义自定义样式,您可以使用以下代码。最终将使用Rectangle,但在自定义样式中,而不是在视图代码中使用。这是你想要的吗?

注意:经过Beta 3测试

要使用自定义初始化程序,请执行以下操作:

struct ContentView : View {
    @State private var username = ""

    var body: some View {
        VStack {

            TextField("Enter text", text: $username)
                .textFieldStyle(.myOwnStyle)

        }.frame(width:300)
    }
}
Run Code Online (Sandbox Code Playgroud)

您的自定义初始化程序实现:

public struct MyOwnTextFieldStyle: TextFieldStyle {
    public func _body(configuration: TextField<Self.Label>) -> some View {

        VStack() {
            configuration
                .border(Color.blue, width: 2)
                .foregroundColor(Color.yellow)
            Rectangle()
                .frame(height: 1.0, alignment: .bottom)
                .relativeWidth(1)
                .foregroundColor(Color.red)

        }
    }
}

extension StaticMember where Base : TextFieldStyle {
    public static var myOwnStyle: MyOwnTextFieldStyle.Member {
        StaticMember<MyOwnTextFieldStyle>(MyOwnTextFieldStyle())
    }
}
Run Code Online (Sandbox Code Playgroud)

  • beta 6 中不再有 StaticMember。有替代品吗? (3认同)