如何调整UISearchBar中清除按钮的位置?
调整UISearchBar清除按钮位置的解决方案
问题背景
需要调整UISearchBar右侧清除按钮(带X的按钮)的位置,目前已通过value(forKey: "searchField")获取内部UITextField完成了搜索栏的样式自定义,但仅能获取清除按钮的矩形区域,无法调整其位置。当前自定义代码如下:
if let searchTextField = value(forKey: "searchField") as? UITextField { searchTextField.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ searchTextField.heightAnchor.constraint(equalToConstant: CGFloat(height)), searchTextField.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0), searchTextField.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0), searchTextField.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0) ]) searchTextField.clipsToBounds = true searchTextField.font = UIFont.regularDMSans(of: 17) searchTextField.textColor = .textLight searchTextField.layer.cornerRadius = 20 searchTextField.layer.borderWidth = 2.0 searchTextField.layer.borderColor = UIColor.createEventDivider.cgColor if !shouldShowSearchIcon { setImage(UIImage(), for: .search, state: .normal) } let offset = UIOffset(horizontal: 13, vertical: 0) setPositionAdjustment(offset, for: .search) }
可行解决方案
方法一:子类化UITextField重写位置计算方法
系统清除按钮的位置由clearButtonRect(forBounds:)方法决定,通过子类化UITextField并重写该方法,可直接调整按钮偏移:
- 创建自定义UITextField子类:
class CustomSearchTextField: UITextField { // 自定义水平偏移量:负数左移,正数右移 var clearButtonHorizontalOffset: CGFloat = -10 // 可选:自定义垂直偏移量 var clearButtonVerticalOffset: CGFloat = 0 override func clearButtonRect(forBounds bounds: CGRect) -> CGRect { let defaultRect = super.clearButtonRect(forBounds: bounds) return CGRect( x: defaultRect.origin.x + clearButtonHorizontalOffset, y: defaultRect.origin.y + clearButtonVerticalOffset, width: defaultRect.width, height: defaultRect.height ) } }
- 在自定义UISearchBar中替换内部TextField:
class CustomSearchBar: UISearchBar { var shouldShowSearchIcon: Bool = true var height: CGFloat = 40 override init(frame: CGRect) { super.init(frame: frame) setupCustomSearchField() } required init?(coder: NSCoder) { super.init(coder: coder) setupCustomSearchField() } private func setupCustomSearchField() { // 替换系统默认TextField为自定义子类 let customTextField = CustomSearchTextField() customTextField.clearButtonHorizontalOffset = -15 // 按需调整偏移值 setValue(customTextField, forKey: "searchField") guard let searchTextField = value(forKey: "searchField") as? CustomSearchTextField else { return } // 原有样式配置 searchTextField.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ searchTextField.heightAnchor.constraint(equalToConstant: height), searchTextField.leadingAnchor.constraint(equalTo: leadingAnchor), searchTextField.trailingAnchor.constraint(equalTo: trailingAnchor), searchTextField.centerYAnchor.constraint(equalTo: centerYAnchor) ]) searchTextField.clipsToBounds = true searchTextField.font = UIFont.regularDMSans(of: 17) searchTextField.textColor = .textLight searchTextField.layer.cornerRadius = 20 searchTextField.layer.borderWidth = 2.0 searchTextField.layer.borderColor = UIColor.createEventDivider.cgColor if !shouldShowSearchIcon { setImage(UIImage(), for: .search, state: .normal) } let offset = UIOffset(horizontal: 13, vertical: 0) setPositionAdjustment(offset, for: .search) } }
方法二:替换为自定义清除按钮
若不想子类化,可直接隐藏系统清除按钮,自定义按钮并通过rightView添加,完全控制位置和样式:
if let searchTextField = value(forKey: "searchField") as? UITextField { // 隐藏系统默认清除按钮 searchTextField.clearButtonMode = .never // 创建自定义清除按钮 let clearButton = UIButton(type: .custom) clearButton.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal) clearButton.tintColor = .gray clearButton.frame = CGRect(x: 0, y: 0, width: 24, height: 24) clearButton.addTarget(self, action: #selector(clearSearchText), for: .touchUpInside) // 调整按钮位置:通过contentEdgeInsets控制偏移 clearButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10) searchTextField.rightView = clearButton searchTextField.rightViewMode = .whileEditing } // 清除文本的响应方法 @objc private func clearSearchText() { (value(forKey: "searchField") as? UITextField)?.text = "" }
内容的提问来源于stack exchange,提问作者İsmail Ege Oğuz
相关产品推荐
相关产品推荐

