swift 如何在右侧设置 UiSearchBar 搜索图标
How to set UiSearchBar Search icon on the right side in swift
我正在研究 Swift。
作为常规 SearchBar 默认情况下,它的外观如下图 (1) 所示。
但根据我们的设计要求,我需要将其更改为如下图(2)。
我尝试使用下面的代码,我得到了如下图 (3)
**当我尝试以下代码时,右视图被隐藏,我无法看到文本字段右视图
搜索图标完全不可见**
let searchField = (searchBar.valueForKey("_searchField") as! UITextField)
searchField.layer.cornerRadius = 15;
let searchIcon = searchField.leftView!
if (searchIcon is UIImageView) {
print("yes")
}
searchField.rightView = searchIcon
searchField.leftViewMode = .Never
searchField.rightViewMode = .Always
任何人都可以帮助我获得要求。我可以理解如果你在 objective C 上也提供
在ViewController中,搜索栏文本框的左视图是实际的搜索图标,因此将其设置为nil并创建一个带有自定义图标的图像视图并设置为搜索文本框的右视图。
Objective C
@interface FirstViewController ()
{
UISearchBar *searchBar;
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
searchBar = [[UISearchBar alloc] init];
searchBar.frame = CGRectMake(15, 100, 350,50);
[self.view addSubview:searchBar];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UITextField *searchTextField = [((UITextField *)[searchBar.subviews objectAtIndex:0]).subviews lastObject];
searchTextField.layer.cornerRadius = 15.0f;
searchTextField.textAlignment = NSTextAlignmentLeft;
UIImage *image = [UIImage imageNamed:@"search"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
searchTextField.leftView = nil;
searchTextField.placeholder = @"Search";
searchTextField.rightView = imageView;
searchTextField.rightViewMode = UITextFieldViewModeAlways;
}
Swift
private var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
searchBar = UISearchBar()
searchBar.frame = CGRect(x: 15, y: 100, width: 350, height: 50)
self.view.addSubview(searchBar)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let searchTextField:UITextField = searchBar.subviews[0].subviews.last as! UITextField
searchTextField.layer.cornerRadius = 15
searchTextField.textAlignment = NSTextAlignment.left
let image:UIImage = UIImage(named: "search")!
let imageView:UIImageView = UIImageView.init(image: image)
searchTextField.leftView = nil
searchTextField.placeholder = "Search"
searchTextField.rightView = imageView
searchTextField.rightViewMode = UITextFieldViewMode.always
}
我建议你查看 Apple 文档 layoutIfNeeded()
和 layoutSubviews() 。阅读它们后,您将有更好的理解。当您编写 searchBar.layoutIfNeeded()
实例方法时,奇迹就会发生。另一个解决方案是 searchBar.layoutSubviews()
但 Apple 文档说:
You should not call this method directly. If you want to force a
layout update, call the setNeedsLayout() method instead to do so prior
to the next drawing update. If you want to update the layout of your
views immediately, call the layoutIfNeeded() method.
根据@Jeyamahesan 的回答。当您修改如下代码时,您无需将 viewDidLoad() 和 ViewDidAppear() 中的代码分开。
示例:
import UIKit
class MainController: UIViewController {
private var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
searchBar = UISearchBar()
searchBar.frame = CGRect(x: 15, y: 100, width: 350, height: 50)
searchBar.layoutIfNeeded()
self.view.addSubview(searchBar)
let searchTextField:UITextField = searchBar.subviews[0].subviews.last as! UITextField
searchTextField.layer.cornerRadius = 15
searchTextField.textAlignment = NSTextAlignment.left
let image:UIImage = UIImage(named: "Search")!
let imageView:UIImageView = UIImageView.init(image: image)
searchTextField.leftView = nil
searchTextField.placeholder = "Search"
searchTextField.rightView = imageView
searchTextField.rightViewMode = UITextFieldViewMode.always
}
}
我解决问题的方法:
MainView.swift
import UIKit
class MainView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func setupUI() {
backgroundColor = UIColor.lightGray
setupSubViews()
setupAutoLayout()
}
// MARK: Initialize UI Elements
private let searchBar: UISearchBar = {
let searchBar = UISearchBar()
searchBar.isTranslucent = false
searchBar.barTintColor = ColorPalette.LuminousDay.white
searchBar.layoutIfNeeded()
return searchBar
}()
private let searchImageView: UIImageView = {
let image = UIImage(named: "Search")
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
return imageView
}()
private lazy var searchBarTextField: UITextField = { [unowned self] in
let textField = self.searchBar.value(forKey: "searchBarTextField") as! UITextField
textField.font = FontBook.SourceSansPro.Weight.semiBold.setFont(size: 24)
textField.textColor = ColorPalette.LuminousDay.charm
textField.tintColor = ColorPalette.LuminousDay.charm
textField.clearButtonMode = .never
textField.leftViewMode = .never
textField.leftView = nil
textField.rightViewMode = .always
textField.rightView = self.searchImageView
return textField
}()
private func setupSubViews() {
addSubview(searchBar)
searchBar.addSubview(searchBarTextField)
searchBarTextField.addSubview(searchImageView)
}
private func setupAutoLayout() {
searchBar.anchor(top: safeAreaLayoutGuide.topAnchor, bottom: nil,
leading: safeAreaLayoutGuide.leadingAnchor, trailing: safeAreaLayoutGuide.trailingAnchor,
centerX: nil, centerY: nil,
centerXconstant: nil, centerYconstant: nil,
size: CGSize.zero, padding: UIEdgeInsets(top: 50, left: 0, bottom: 0, right: 0))
searchImageView.setSize(size: CGSize(width: 16, height: 16))
}
}
MainController.swift
import UIKit
class MainController: UIViewController {
override func loadView() {
view = MainView()
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Switf 5
参考Jeyamahesan的回答。
我发现 viewDidLayoutSubviews 比 viewDidAppear 更有机会。如果您在 viewDidAppear 中调用 setupSearchTextField(),您将在 searchTextField 上看到一个快速变化。
因为viewDidLayoutSubviews第一次会被调用两次,后面会调用很多次。所以我添加了一个 isFirst 变量。
R.string.localizable.product_name() -> 这是一个很好的资源框架,您可以在此处找到更多详细信息。
https://github.com/mac-cain13/R.swift
private var isFirst = true
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard isFirst else {
return
}
isFirst = false
setupSearchTextField()
}
private func setupSearchTextField() {
let searchTextField = searchBar.searchTextField
searchTextField.backgroundColor = .white
searchTextField.layer.borderColor = UIColor(hex: "707070").cgColor
searchTextField.layer.borderWidth = 1
searchTextField.placeholder = R.string.localizable.product_name()
let imageView = UIImageView(image: R.image.searchIcon())
searchTextField.rightView = imageView
searchTextField.rightViewMode = UITextField.ViewMode.always
//delegate
searchBar.delegate = self
}
试试这个,然后调用 viewDidLayoutSubviews()
func SearchText(to searchBar: UISearchBar, placeHolderText: String) {
searchBar.barTintColor = UIColor.clear
searchBar.backgroundColor = UIColor.clear
searchBar.isTranslucent = true
searchBar.setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
let searchTextField:UITextField = searchBar.value(forKey: "searchField") as? UITextField ?? UITextField()
searchTextField.layer.cornerRadius = 15
searchTextField.textAlignment = NSTextAlignment.left
let image:UIImage = UIImage(named: "search")!
let imageView:UIImageView = UIImageView.init(image: image)
searchTextField.leftView = nil
searchTextField.font = UIFont.textFieldText
searchTextField.attributedPlaceholder = NSAttributedString(string: placeHolderText,attributes: [NSAttributedString.Key.foregroundColor: UIColor.yourCOlur])
searchTextField.rightView = imageView
searchTextField.backgroundColor = UIColor.yourCOlur
searchTextField.rightViewMode = UITextField.ViewMode.always
}
这是 swift 5 和 ios 13 或更高版本
中故事板的完整搜索视图自定义
@IBOutlet weak var searchview: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
//make background vertical line
searchview.backgroundImage = UIImage()
if #available(iOS 13.0, *) {
let searchTextField:UITextField = searchview.searchTextField
searchTextField.textAlignment = .left
searchTextField.layer.cornerRadius = 20
searchTextField.layer.masksToBounds = true
searchTextField.rightView = nil
//your custom icon here
let image:UIImage = UIImage(named: "Search")!
let imageV:UIImageView = UIImageView.init(image: image)
searchTextField.rightView = nil
searchTextField.placeholder = "Search"
searchTextField.leftView = imageV
//dafault search icon
let imageV = searchTextField.leftView as! UIImageView
imageV.image = imageV.image?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
imageV.tintColor = UIColor.lightGray
}
}
我正在研究 Swift。
作为常规 SearchBar 默认情况下,它的外观如下图 (1) 所示。
但根据我们的设计要求,我需要将其更改为如下图(2)。
我尝试使用下面的代码,我得到了如下图 (3)
**当我尝试以下代码时,右视图被隐藏,我无法看到文本字段右视图
搜索图标完全不可见**
let searchField = (searchBar.valueForKey("_searchField") as! UITextField)
searchField.layer.cornerRadius = 15;
let searchIcon = searchField.leftView!
if (searchIcon is UIImageView) {
print("yes")
}
searchField.rightView = searchIcon
searchField.leftViewMode = .Never
searchField.rightViewMode = .Always
任何人都可以帮助我获得要求。我可以理解如果你在 objective C 上也提供
在ViewController中,搜索栏文本框的左视图是实际的搜索图标,因此将其设置为nil并创建一个带有自定义图标的图像视图并设置为搜索文本框的右视图。
Objective C
@interface FirstViewController ()
{
UISearchBar *searchBar;
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
searchBar = [[UISearchBar alloc] init];
searchBar.frame = CGRectMake(15, 100, 350,50);
[self.view addSubview:searchBar];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UITextField *searchTextField = [((UITextField *)[searchBar.subviews objectAtIndex:0]).subviews lastObject];
searchTextField.layer.cornerRadius = 15.0f;
searchTextField.textAlignment = NSTextAlignmentLeft;
UIImage *image = [UIImage imageNamed:@"search"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
searchTextField.leftView = nil;
searchTextField.placeholder = @"Search";
searchTextField.rightView = imageView;
searchTextField.rightViewMode = UITextFieldViewModeAlways;
}
Swift
private var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
searchBar = UISearchBar()
searchBar.frame = CGRect(x: 15, y: 100, width: 350, height: 50)
self.view.addSubview(searchBar)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let searchTextField:UITextField = searchBar.subviews[0].subviews.last as! UITextField
searchTextField.layer.cornerRadius = 15
searchTextField.textAlignment = NSTextAlignment.left
let image:UIImage = UIImage(named: "search")!
let imageView:UIImageView = UIImageView.init(image: image)
searchTextField.leftView = nil
searchTextField.placeholder = "Search"
searchTextField.rightView = imageView
searchTextField.rightViewMode = UITextFieldViewMode.always
}
我建议你查看 Apple 文档 layoutIfNeeded()
和 layoutSubviews() 。阅读它们后,您将有更好的理解。当您编写 searchBar.layoutIfNeeded()
实例方法时,奇迹就会发生。另一个解决方案是 searchBar.layoutSubviews()
但 Apple 文档说:
You should not call this method directly. If you want to force a layout update, call the setNeedsLayout() method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded() method.
根据@Jeyamahesan 的回答。当您修改如下代码时,您无需将 viewDidLoad() 和 ViewDidAppear() 中的代码分开。
示例:
import UIKit
class MainController: UIViewController {
private var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
searchBar = UISearchBar()
searchBar.frame = CGRect(x: 15, y: 100, width: 350, height: 50)
searchBar.layoutIfNeeded()
self.view.addSubview(searchBar)
let searchTextField:UITextField = searchBar.subviews[0].subviews.last as! UITextField
searchTextField.layer.cornerRadius = 15
searchTextField.textAlignment = NSTextAlignment.left
let image:UIImage = UIImage(named: "Search")!
let imageView:UIImageView = UIImageView.init(image: image)
searchTextField.leftView = nil
searchTextField.placeholder = "Search"
searchTextField.rightView = imageView
searchTextField.rightViewMode = UITextFieldViewMode.always
}
}
我解决问题的方法:
MainView.swift
import UIKit
class MainView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func setupUI() {
backgroundColor = UIColor.lightGray
setupSubViews()
setupAutoLayout()
}
// MARK: Initialize UI Elements
private let searchBar: UISearchBar = {
let searchBar = UISearchBar()
searchBar.isTranslucent = false
searchBar.barTintColor = ColorPalette.LuminousDay.white
searchBar.layoutIfNeeded()
return searchBar
}()
private let searchImageView: UIImageView = {
let image = UIImage(named: "Search")
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
return imageView
}()
private lazy var searchBarTextField: UITextField = { [unowned self] in
let textField = self.searchBar.value(forKey: "searchBarTextField") as! UITextField
textField.font = FontBook.SourceSansPro.Weight.semiBold.setFont(size: 24)
textField.textColor = ColorPalette.LuminousDay.charm
textField.tintColor = ColorPalette.LuminousDay.charm
textField.clearButtonMode = .never
textField.leftViewMode = .never
textField.leftView = nil
textField.rightViewMode = .always
textField.rightView = self.searchImageView
return textField
}()
private func setupSubViews() {
addSubview(searchBar)
searchBar.addSubview(searchBarTextField)
searchBarTextField.addSubview(searchImageView)
}
private func setupAutoLayout() {
searchBar.anchor(top: safeAreaLayoutGuide.topAnchor, bottom: nil,
leading: safeAreaLayoutGuide.leadingAnchor, trailing: safeAreaLayoutGuide.trailingAnchor,
centerX: nil, centerY: nil,
centerXconstant: nil, centerYconstant: nil,
size: CGSize.zero, padding: UIEdgeInsets(top: 50, left: 0, bottom: 0, right: 0))
searchImageView.setSize(size: CGSize(width: 16, height: 16))
}
}
MainController.swift
import UIKit
class MainController: UIViewController {
override func loadView() {
view = MainView()
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Switf 5
参考Jeyamahesan的回答。
我发现 viewDidLayoutSubviews 比 viewDidAppear 更有机会。如果您在 viewDidAppear 中调用 setupSearchTextField(),您将在 searchTextField 上看到一个快速变化。
因为viewDidLayoutSubviews第一次会被调用两次,后面会调用很多次。所以我添加了一个 isFirst 变量。
R.string.localizable.product_name() -> 这是一个很好的资源框架,您可以在此处找到更多详细信息。 https://github.com/mac-cain13/R.swift
private var isFirst = true
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard isFirst else {
return
}
isFirst = false
setupSearchTextField()
}
private func setupSearchTextField() {
let searchTextField = searchBar.searchTextField
searchTextField.backgroundColor = .white
searchTextField.layer.borderColor = UIColor(hex: "707070").cgColor
searchTextField.layer.borderWidth = 1
searchTextField.placeholder = R.string.localizable.product_name()
let imageView = UIImageView(image: R.image.searchIcon())
searchTextField.rightView = imageView
searchTextField.rightViewMode = UITextField.ViewMode.always
//delegate
searchBar.delegate = self
}
试试这个,然后调用 viewDidLayoutSubviews()
func SearchText(to searchBar: UISearchBar, placeHolderText: String) {
searchBar.barTintColor = UIColor.clear
searchBar.backgroundColor = UIColor.clear
searchBar.isTranslucent = true
searchBar.setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
let searchTextField:UITextField = searchBar.value(forKey: "searchField") as? UITextField ?? UITextField()
searchTextField.layer.cornerRadius = 15
searchTextField.textAlignment = NSTextAlignment.left
let image:UIImage = UIImage(named: "search")!
let imageView:UIImageView = UIImageView.init(image: image)
searchTextField.leftView = nil
searchTextField.font = UIFont.textFieldText
searchTextField.attributedPlaceholder = NSAttributedString(string: placeHolderText,attributes: [NSAttributedString.Key.foregroundColor: UIColor.yourCOlur])
searchTextField.rightView = imageView
searchTextField.backgroundColor = UIColor.yourCOlur
searchTextField.rightViewMode = UITextField.ViewMode.always
}
这是 swift 5 和 ios 13 或更高版本
中故事板的完整搜索视图自定义 @IBOutlet weak var searchview: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
//make background vertical line
searchview.backgroundImage = UIImage()
if #available(iOS 13.0, *) {
let searchTextField:UITextField = searchview.searchTextField
searchTextField.textAlignment = .left
searchTextField.layer.cornerRadius = 20
searchTextField.layer.masksToBounds = true
searchTextField.rightView = nil
//your custom icon here
let image:UIImage = UIImage(named: "Search")!
let imageV:UIImageView = UIImageView.init(image: image)
searchTextField.rightView = nil
searchTextField.placeholder = "Search"
searchTextField.leftView = imageV
//dafault search icon
let imageV = searchTextField.leftView as! UIImageView
imageV.image = imageV.image?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
imageV.tintColor = UIColor.lightGray
}
}