You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UITextField中同时显示清除按钮与单位标签(仿苹果健康App)

复刻苹果健康App体重输入框交互的解决方案

UIKit 实现方案

系统默认的 UITextField 会让 rightView 覆盖自带的清除按钮,因此需要自定义容器视图整合单位标签和清除按钮,再手动控制清除按钮的显示逻辑。

代码示例

// 初始化TextField
let textField = UITextField(frame: CGRect(x: 20, y: 100, width: 300, height: 44))
textField.placeholder = "输入体重"
textField.borderStyle = .roundedRect

// 创建容器视图,适配标签和按钮的宽度
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 65, height: textField.frame.height))

// 添加单位标签
let unitLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 35, height: containerView.frame.height))
unitLabel.text = "kg"
unitLabel.textAlignment = .center
unitLabel.font = textField.font
containerView.addSubview(unitLabel)

// 添加自定义清除按钮
let clearButton = UIButton(type: .system)
clearButton.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal)
clearButton.tintColor = .systemGray
clearButton.frame = CGRect(x: unitLabel.frame.maxX + 5, y: (containerView.frame.height - 22)/2, width: 22, height: 22)
clearButton.addTarget(self, action: #selector(clearText), for: .touchUpInside)
clearButton.isHidden = true // 默认隐藏
containerView.addSubview(clearButton)

// 配置TextField
textField.rightView = containerView
textField.rightViewMode = .always
textField.addTarget(self, action: #selector(updateClearButtonVisibility), for: .editingDidBegin)
textField.addTarget(self, action: #selector(updateClearButtonVisibility), for: .editingDidEnd)
textField.addTarget(self, action: #selector(updateClearButtonVisibility), for: .editingChanged)

// 清除文本方法
@objc func clearText() {
    textField.text = ""
    updateClearButtonVisibility()
}

// 更新清除按钮显示状态
@objc func updateClearButtonVisibility() {
    guard let clearButton = textField.rightView?.subviews.first(where: { $0 is UIButton }) as? UIButton else { return }
    clearButton.isHidden = !textField.isEditing || (textField.text?.isEmpty ?? true)
}

逻辑说明

  • 关闭系统自带的 clearButtonMode,改用自定义按钮避免和 rightView 冲突
  • 监听编辑状态和文本内容变化,控制清除按钮的显示/隐藏,和系统 .whileEditing 逻辑一致
  • 容器视图确保单位标签始终显示,清除按钮仅在编辑且文本非空时出现

SwiftUI 实现方案

SwiftUI 可通过 overlay 直接在 TextField 上叠加组合视图,配合 @FocusState 追踪编辑状态,快速实现需求。

代码示例

struct WeightInputView: View {
    @State private var weightText = ""
    @FocusState private var isEditing: Bool
    
    var body: some View {
        TextField("输入体重", text: $weightText)
            .focused($isEditing)
            .padding(.horizontal, 16)
            .padding(.vertical, 12)
            .border(Color(.systemGray4), cornerRadius: 8)
            .overlay(alignment: .trailing) {
                HStack(spacing: 8) {
                    Text("kg")
                        .foregroundColor(.secondary)
                        .font(.system(size: 16))
                    
                    if isEditing && !weightText.isEmpty {
                        Button(action: { weightText = "" }) {
                            Image(systemName: "xmark.circle.fill")
                                .foregroundColor(.secondary)
                                .font(.system(size: 18))
                        }
                    }
                }
                .padding(.trailing, 16)
            }
            .onTapGesture {
                isEditing = true
            }
    }
}

逻辑说明

  • 使用 @FocusState 监测 TextField 是否处于编辑状态
  • 通过 overlay 在右侧叠加单位标签和条件显示的清除按钮
  • 清除按钮仅在编辑且文本非空时显示,单位标签始终可见,完全匹配健康App的交互效果

内容的提问来源于stack exchange,提问作者Kngw Kngw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:47:20