Как установить значок поиска 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
}
Другие вопросы по тегам