How to set UiSearchBar Search icon on the right side in swift

Clash Royale CLAN TAG#URR8PPPHow to set UiSearchBar Search icon on the right side in swift
I am working on Swift.
As regular SearchBar By default its appearing like Following Pic(1).
But as per our design requirement I need to change it as Following Pic(2).

I tried using the following code I got like Following Pic(3)

**When I tried the following code the right view is getting hide and I could not able to see the text field rightview
Search icon completely invisible**
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
Can anyone help me to get the requirement. I can understand if you provide even on objective C as well
2 Answers
2
In ViewController, leftview of searchbar textfield is the actual search icon, so make it to nil and create a image view with custom icon and set as a right view of search textfield.
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
}

I suggest you to check Apple documentation layoutIfNeeded()
and layoutSubviews() . You'll have better understanding after reading them. The magic happens when you write searchBar.layoutIfNeeded() instance method. Another solution is searchBar.layoutSubviews() but Apple documentation says:
searchBar.layoutIfNeeded()
searchBar.layoutSubviews()
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.
According to @Jeyamahesan's answer. When you modify the code like below you do not need to separate the code in viewDidLoad() and ViewDidAppear().
Example:
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
}
}
My approach to solve the issue:
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()
}
}
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thank you, the whole magic is in viewDidAppear method :)
– iOS dev
Oct 26 '16 at 7:19