SwiftUI中TextField选中时如何高亮默认值或显示占位符?
SwiftUI温度转换APP TextField优化方案
针对你提出的两种需求,分别提供简单实现方式:
方案b:显示占位符,无默认值
这种方式更符合用户输入习惯,未输入时显示"Temperature"占位符,输入后展示内容。只需将温度变量改为可选类型,处理计算时的默认值即可:
import SwiftUI struct ContentView: View { @State private var temp: Int? = nil // 改为可选Int,初始为nil @State private var tempUnit: String = "" @State private var tempConvertUnit: String = "" var convertedTemp: Int { let inputTemp = temp ?? 0 // 未输入时用0作为计算默认值 switch tempUnit { case "F": return tempConvertUnit == "C" ? Int((inputTemp - 32) * 5 / 9) : inputTemp case "C": return tempConvertUnit == "F" ? Int(inputTemp * 9/5 + 32) : inputTemp default: return inputTemp } } let tempUnits = ["F", "C"] @FocusState private var amountIsFocused: Bool var body: some View { NavigationStack{ Form{ Section("Temperature"){ TextField("Temperature", value: $temp, format: .number) .keyboardType(.decimalPad) .focused($amountIsFocused) Picker("Unit", selection: $tempUnit){ ForEach(tempUnits, id: \.self) { Text($0) } }.pickerStyle(.segmented) } Section("Converted Temperature"){ Text(convertedTemp, format: .number) Picker("Unit", selection: $tempConvertUnit){ ForEach(tempUnits, id: \.self) { Text($0) } }.pickerStyle(.segmented) } } .navigationTitle("Converter") .toolbar { if amountIsFocused { Button("Done") { amountIsFocused = false } } } } } }
方案a:选中TextField时高亮默认值,输入自动覆盖
通过监听焦点状态,利用UIKit API实现选中全部文本,输入时直接覆盖默认值:
首先添加UIView扩展用于查找TextField:
extension UIView { func findTextField() -> UITextField? { if let textField = self as? UITextField { return textField } for subview in subviews { if let textField = subview.findTextField() { return textField } } return nil } }
然后修改ContentView中的TextField部分,添加焦点变化监听:
TextField("Temperature", value: $temp, format: .number) .keyboardType(.decimalPad) .focused($amountIsFocused) .onChange(of: amountIsFocused) { _, isFocused in guard isFocused else { return } DispatchQueue.main.async { let activeScene = UIApplication.shared.connectedScenes .filter { $0.activationState == .foregroundActive } .first as? UIWindowScene let keyWindow = activeScene?.windows.first(where: { $0.isKeyWindow }) keyWindow?.rootViewController?.view.findTextField()?.selectAll(nil) } }
这样当TextField获得焦点时,默认值0会被全部选中,输入新内容会直接覆盖。
内容的提问来源于stack exchange,提问作者Laura Mansfield
相关产品推荐
相关产品推荐

