MST

星途 面试题库

面试题:SwiftUI中TextField与TextEditor的自定义样式与交互优化

在SwiftUI项目中,你需要为TextField和TextEditor创建自定义样式,使其在外观上与应用整体风格一致,例如改变文本框边框样式、文本颜色、占位文本颜色等。同时,优化它们的交互体验,比如当TextField获得焦点时,自动弹出特定的键盘类型(如数字键盘用于输入金额),TextEditor在达到最大输入长度时给出友好的提示且禁止继续输入。请详细描述实现思路,并给出关键代码示例。
12.4万 热度难度
编程语言Swift

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 自定义样式
    • 文本框边框样式:使用TextFieldTextEditoroverlay修饰符来添加自定义边框。可以通过RoundedRectangle绘制边框,并设置其颜色、线宽等属性。
    • 文本颜色:直接使用foregroundColor修饰符来改变文本颜色。
    • 占位文本颜色:对于TextField,可以通过attributedPlaceholder来设置占位文本的颜色等属性。对于TextEditor,需要自定义一个类似占位文本的功能,在文本为空时显示特定文本,并设置其颜色。
  2. 优化交互体验
    • TextField焦点与键盘类型:使用@FocusState来检测TextField是否获得焦点,当获得焦点时,通过keyboardType修饰符设置特定的键盘类型,如UIKeyboardType.decimalPad用于金额输入。
    • TextEditor最大输入长度:使用@State来存储输入的文本,并在onChange事件中检测文本长度,当达到最大长度时,给出提示并禁止继续输入。可以通过设置TextEditorisEditable属性来禁止输入。

关键代码示例

import SwiftUI

struct CustomTextField: View {
    @FocusState private var isFocused: Bool
    @Binding var text: String
    let placeholder: String
    let keyboardType: UIKeyboardType
    let maxLength: Int?

    var body: some View {
        VStack {
            TextField(placeholder, text: $text)
              .focused($isFocused)
              .keyboardType(keyboardType)
              .foregroundColor(.black)
              .padding()
              .overlay(
                    RoundedRectangle(cornerRadius: 8)
                      .stroke(isFocused ? Color.blue : Color.gray, lineWidth: 1)
                )
              .attributedPlaceholder(
                    NSAttributedString(string: placeholder, attributes: [NSAttributedString.Key.foregroundColor: Color.gray])
                )
              .onChange(of: text) { newValue in
                    if let maxLength = maxLength, newValue.count > maxLength {
                        text = String(newValue.prefix(maxLength))
                    }
                }
        }
    }
}

struct CustomTextEditor: View {
    @State private var text = ""
    let placeholder: String
    let maxLength: Int

    var body: some View {
        VStack {
            TextEditor(text: $text)
              .foregroundColor(.black)
              .padding()
              .overlay(
                    RoundedRectangle(cornerRadius: 8)
                      .stroke(Color.gray, lineWidth: 1)
                )
              .onChange(of: text) { newValue in
                    if newValue.count > maxLength {
                        text = String(newValue.prefix(maxLength))
                        // 给出友好提示,这里简单使用打印示例
                        print("已达到最大输入长度")
                    }
                }
            if text.isEmpty {
                Text(placeholder)
                  .foregroundColor(.gray)
                  .padding(.horizontal, 16)
            }
        }
    }
}

struct ContentView: View {
    @State private var amountText = ""
    @State private var editorText = ""

    var body: some View {
        VStack {
            CustomTextField(text: $amountText, placeholder: "请输入金额", keyboardType:.decimalPad, maxLength: 10)
            CustomTextEditor(placeholder: "请输入内容", maxLength: 200)
        }
        .padding()
    }
}