Swift5中如何搭配MDCOutlinedTextField使用Material Chips组件
实现MDCOutlinedTextField内嵌Material Chips的Swift方案
核心思路为自定义继承自MDCOutlinedTextField的控件,将MDCChipView组件放入输入框内部容器中,同时调整输入文本的缩进距离避免和Chips重叠,具体实现步骤如下:
步骤1:集成依赖
首先确认你已集成Material Components iOS库,使用CocoaPods的话在Podfile中添加以下配置:
pod 'MaterialComponents/TextFields' pod 'MaterialComponents/Chips'
执行pod install完成集成后,在需要使用的文件中导入对应模块:
import MaterialComponents.MDCOutlinedTextField import MaterialComponents.MDCChipView
步骤2:自定义带Chips的文本框控件
class ChipsOutlinedTextField: MDCOutlinedTextField { // 承载多个Chip的堆栈容器 private let chipsStackView: UIStackView = { let stack = UIStackView() stack.axis = .horizontal stack.spacing = 8 stack.alignment = .center stack.translatesAutoresizingMaskIntoConstraints = false return stack }() override init(frame: CGRect) { super.init(frame: frame) setupContainer() } required init?(coder: NSCoder) { super.init(coder: coder) setupContainer() } private func setupContainer() { addSubview(chipsStackView) // 配置Chip容器约束:居左对齐、上下居中、固定高度适配Chip尺寸 NSLayoutConstraint.activate([ chipsStackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12), chipsStackView.centerYAnchor.constraint(equalTo: centerYAnchor), chipsStackView.heightAnchor.constraint(equalToConstant: 32) ]) } // 重写方法调整非编辑状态下文本的起始位置,给Chip留出显示空间 override func textRect(forBounds bounds: CGRect) -> CGRect { var originRect = super.textRect(forBounds: bounds) originRect.origin.x += chipsStackView.frame.width + 8 return originRect } // 重写方法调整编辑状态下文本的起始位置 override func editingRect(forBounds bounds: CGRect) -> CGRect { var originRect = super.editingRect(forBounds: bounds) originRect.origin.x += chipsStackView.frame.width + 8 return originRect } // 对外暴露添加Chip的方法 func addChip(title: String) { let chip = MDCChipView() chip.titleLabel.text = title chip.setBackgroundColor(.systemGray5, for: .normal) chip.setTitleColor(.label, for: .normal) chip.sizeToFit() // 绑定点击Chip删除的事件 chip.addTarget(self, action: #selector(removeChip(_:)), for: .touchUpInside) chipsStackView.addArrangedSubview(chip) // 刷新布局更新文本缩进 setNeedsLayout() layoutIfNeeded() } @objc private func removeChip(_ sender: MDCChipView) { sender.removeFromSuperview() setNeedsLayout() } }
步骤3:调用示例
// 初始化自定义文本框 let contactTextField = ChipsOutlinedTextField(frame: CGRect(x: 20, y: 100, width: view.frame.width - 40, height: 56)) contactTextField.label.text = "收件人" contactTextField.placeholder = "输入姓名或邮箱" // 添加测试Chip contactTextField.addChip(title: "张三") contactTextField.addChip(title: "李四") view.addSubview(contactTextField)
可选优化点
- 若Chips数量过多需要换行,可将stackView替换为支持流式布局的UICollectionView,实现多行排列效果
- 可根据设计需求自定义Chip的样式,包括背景色、圆角、删除图标、选中高亮效果等
- 若需要输入完成后自动生成Chip,可在
UITextFieldDelegate的textFieldShouldReturn(_:)方法中读取当前输入文本,调用addChip方法后清空输入内容即可
内容的提问来源于stack exchange,提问作者Poom Wutthidech
相关产品推荐
相关产品推荐

