Как установить значок поиска UiSearchBar на правой стороне в Swift
Я работаю над Swift.
Как обычный SearchBar По умолчанию он выглядит следующим образом: Pic(1).
Но в соответствии с нашим требованием к дизайну, мне нужно изменить его следующим образом (2).
Я попытался использовать следующий код, который я получил, как Follow Pic (3)
** Когда я попробовал следующий код, правильное представление становится скрытым, и я не мог видеть текстовое поле rightview
Значок поиска совершенно невидим **
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, а
5 ответов
В ViewController левое представление текстового поля панели поиска является действительным значком поиска, поэтому сделайте его равным нулю и создайте представление изображения с пользовательским значком и установите в качестве правого представления текстовое поле поиска.
Цель С
@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
}
Я предлагаю вам проверить документацию 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()
}
}
Попробуйте это и вызовите 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
}
}
Switf 5
Ссылка на ответ Джеямахесана。
Я обнаружил, что у viewDidLayoutSubviews больше шансов, чем у viewDidAppear. Если вы вызовете setupSearchTextField() в viewDidAppear, вы увидите мгновенное изменение 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
}