我正在研究Swift。
作为常规SearchBar默认情况下,它显示为Follow Pic(1)。
但根据我们的设计要求,我需要将其更改为以下Pic(2)。
我尝试使用以下代码,如下面的Pic(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
任何人都可以帮助我获得要求。我能理解你是否也提供了目标C
答案 0 :(得分:19)
在ViewController中,搜索栏文本字段的左视图是实际搜索图标,因此将其设置为nil并创建带有自定义图标的图像视图,并将其设置为搜索文本字段的右视图。
目标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;
}
<强>夫特强>
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
}
答案 1 :(得分:3)
我建议您检查Apple文档layoutIfNeeded()
和layoutSubviews()。阅读它们后,您将更好地理解它们。当您编写searchBar.layoutIfNeeded()
实例方法时,魔术就会发生。另一个解决方案是searchBar.layoutSubviews()
,但Apple文档说:
您不应直接调用此方法。如果要强制 布局更新,请先调用setNeedsLayout()方法 到下一个图纸更新。如果您想更新您的布局 立即查看,请调用layoutIfNeeded()方法。
根据@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()
}
}
答案 2 :(得分:1)
这是在 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
}
}
答案 3 :(得分:0)
瑞士法郎5
参考Jeyamahesan的答案。
我发现viewDidLayoutSubviews比viewDidAppear更好。如果您在viewDidAppear中调用setupSearchTextField(),则会在searchTextField上看到Flash更改。
因为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
}
答案 4 :(得分:0)
尝试一下,然后调用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
}