How to change the size of titleView in navigation bar. Because there's a gap between titleView and backButton in navigationBar - ios

I've added a search bar to my navigation.titleView
self.navigationItem.titleView = searchBar
There's also a BackBarButtonItem with title = ""
self.navigationItem.backBarButtonItem?.title = ""
But then there're gap between Back Button and SearchBar, like this:
I Think that the gap appears here because there's space for title of backBarButtonItem (because my title is null "" but the space still there)
So I want to ask how to omit that gap? I want to make my searchBar nearer my backBarIcon
Thank you so much!
EDIT 1:
I try to change searchBar's frame but it's not working
This is my code
//Change searchBar's frame
let titleViewFrame = (searchController.searchBar.frame)
searchController.searchBar.frame = CGRect(x: titleViewFrame.minX - 20.0, y: titleViewFrame.minY, width: titleViewFrame.width + 20.0, height: titleViewFrame.height)

override func viewDidLoad() {
super.viewDidLoad()
let container = UIView(frame: CGRect(x: 0, y: 0, width: 1000, height: 22))
let searchBar = UISearchBar()
searchBar.translatesAutoresizingMaskIntoConstraints = false
container.addSubview(searchBar)
let leftButtonWidth: CGFloat = 35 // left padding
let rightButtonWidth: CGFloat = 75 // right padding
let width = view.frame.width - leftButtonWidth - rightButtonWidth
let offset = (rightButtonWidth - leftButtonWidth) / 2
NSLayoutConstraint.activate([
searchBar.topAnchor.constraint(equalTo: container.topAnchor),
searchBar.bottomAnchor.constraint(equalTo: container.bottomAnchor),
searchBar.centerXAnchor.constraint(equalTo: container.centerXAnchor, constant: -offset),
searchBar.widthAnchor.constraint(equalToConstant: width)
])
self.navigationItem.titleView = container
}

You can't do that, there is a default space given which we cannot change if we have back button.
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "back")
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "back")
self.navigationController?.navigationBar.tintColor = UIColor.lightGray
Below is the screenshot

class SearchBarContainerView: UIView {
let searchBar: UISearchBar
init(customSearchBar: UISearchBar) {
searchBar = customSearchBar
super.init(frame: CGRect.zero)
addSubview(searchBar)
}
override convenience init(frame: CGRect) {
self.init(customSearchBar: UISearchBar())
self.frame = frame
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
searchBar.frame = bounds
}
}
class MyViewController: UIViewController {
func setupNavigationBar() {
let searchBar = UISearchBar()
let searchBarContainer = SearchBarContainerView(customSearchBar: searchBar)
searchBarContainer.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44)
navigationItem.titleView = searchBarContainer
}
}

Related

Can't hide the top and bottom lines in custom searchBar

I´ve tried to change background color inside class SearchBarView: UIView {}:
searchBar.searchTextField.backgroundColor = .clear
searchBar.backgroundColor = .clear
and tryed something like that inside MainViewController:
searchBar.searchTextField.backgroundColor = .clear
searchBar.backgroundColor = .clear
searchBar.layer.backgroundColor = UIColor.clear.cgColor
but, unfortunately I still see this lines inside my custom searchBar.
How can I get rid of these lines?
My SearchBarView class:
class SearchBarView: UIView {
lazy var searchBar = createSearchBar()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(searchBar)
searchBar.snp.makeConstraints { make in
make.leading.equalTo(32)
make.centerY.equalToSuperview()
make.height.equalTo(34)
make.width.equalTo(300)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
fileprivate extension SearchBarView {
private func createSearchBar() -> UISearchBar {
let searchBar = UISearchBar()
searchBar.placeholder = " Search"
searchBar.searchTextField.font = UIFont(name: "MarkPro", size: 15)
searchBar.searchTextField.backgroundColor = .clear
let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField
let imageV = textFieldInsideSearchBar?.leftView as! UIImageView
imageV.image = imageV.image?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
imageV.tintColor = UIColor(hexString: "FF6E4E")
return searchBar
}
}
My MainViewController class:
class MainViewController: UIViewController {
private var searchBarView: SearchBarView!
override func viewDidLoad() {
super.viewDidLoad()
setupSearchBarView()
}
private func setupSearchBarView() {
searchBarView = SearchBarView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
view.addSubview(searchBarView)
searchBarView.searchBar.clipsToBounds = true
searchBarView.searchBar.layer.cornerRadius = 17
searchBarView.searchBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner]
searchBarView.searchBar.searchTextField.clipsToBounds = true
let directionalMargins = NSDirectionalEdgeInsets(top: 0, leading: 24, bottom: 0, trailing: 0)
searchBarView.searchBar.directionalLayoutMargins = directionalMargins
searchBarView.snp.makeConstraints { make in
make.leading.equalToSuperview()
make.top.equalTo(categoriesView.snp.bottom)
make.trailing.equalToSuperview()
make.height.equalTo(60)
}
}
}
If you want to make the top and bottom border lines on the textfield disappear (the dark gray ones), you will want to tweak the text field's border properties rather than the background colors. Try something like this:
searchBar.searchTextField.layer.borderWidth = 0
or
searchBar.searchTextField.layer.borderColor = UIColor.clear.cgColor
and adapt it to fit how you've set up the relevant subviews in your custom search bar.
Set the searchBar background image to empty. This eliminates all background issues you may have such as unwanted lines. For more info reference Apple docs: https://developer.apple.com/documentation/uikit/uisearchbar/1624276-backgroundimage
searchBar.backgroundImage = UIImage()

inputAccessoryView not respecting safeAreaLayoutGuide when keyboard is collapsed

I am trying to get an inputAccessoryView working correctly. Namely, I want to be able to display, in this case, a UIToolbar in two possible states:
Above the keyboard - standard and expected behavior
At the bottom of the screen when the keyboard is dismissed (e.g. command + K in the simulator) - and in such instances, have the bottomAnchor respect the bottom safeAreaLayoutGuide.
I've researched this topic extensively but every suggestion I can find has a bunch of workarounds that don't seem to align with Apple engineering's suggested solution. Based on an openradar ticket, Apple engineering proposed this solution be approached as follows:
It’s your responsibility to respect the input accessory view’s
safeAreaInsets. We designed it this way so developers could provide a
background view (i.e., see Safari’s Find on Page input accessory view)
and lay out the content view with respect to safeAreaInsets. This is
fairly straightforward to accomplish. Have a view hierarchy where you
have a container view and a content view. The container view can have
a background color or a background view that encompasses its entire
bounds, and it lays out it’s content view based on safeAreaInsets. If
you’re using autolayout, this is as simple as setting the content
view’s bottomAnchor to be equal to it’s superview’s
safeAreaLayoutGuide.
The link for the above is: http://www.openradar.me/34411433
I have therefore constructed a simple xCode project (iOS App template) that has the following code:
class ViewController: UIViewController {
var field = UITextField()
var containerView = UIView()
var contentView = UIView()
var toolbar = UIToolbar()
override func viewDidLoad() {
super.viewDidLoad()
// TEXTFIELD
field = UITextField(frame: CGRect(x: 20, y: 100, width: view.frame.size.width, height: 50))
field.placeholder = "Enter name..."
field.backgroundColor = .secondarySystemBackground
field.inputAccessoryView = containerView
view.addSubview(field)
// CONTAINER VIEW
containerView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50)
containerView.backgroundColor = .systemYellow
containerView.translatesAutoresizingMaskIntoConstraints = false
// CONTENT VIEW
contentView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50)
contentView.backgroundColor = .systemPink
contentView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(contentView)
// TOOLBAR
toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(didTapDone))
toolbar.setItems([flexibleSpace, doneButton], animated: true)
toolbar.backgroundColor = .systemGreen
toolbar.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(toolbar)
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: containerView.topAnchor),
contentView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: contentView.superview!.safeAreaLayoutGuide.bottomAnchor),
toolbar.topAnchor.constraint(equalTo: contentView.topAnchor),
toolbar.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
toolbar.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
toolbar.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
}
#objc private func didTapDone() {
print("done tapped")
}
}
The result works whilst the keyboard is visible but doesn't once the keyboard is dimissed:
I've played around with the heights of the various views with mixed results and making the container view frame height larger (e.g. 100), does show the toolbar when the keyboard is collapsed, it also makes the toolbar too tall for when the keyboard is visible.
Clearly I'm making some auto layout constraint issues but I can't work out and would appreciate any feedback that provides a working solution aligned with Apple's recommendation.
Thanks in advance.
In my case I use the following approach:
import UIKit
extension UIView {
func setDimensions(height: CGFloat, width: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
heightAnchor.constraint(equalToConstant: height).isActive = true
widthAnchor.constraint(equalToConstant: width).isActive = true
}
func setHeight(_ height: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
heightAnchor.constraint(equalToConstant: height).isActive = true
}
}
class CustomTextField: UITextField {
override init(frame: CGRect) {
super.init(frame: frame)
}
convenience init(placeholder: String) {
self.init(frame: .zero)
configureUI(placeholder: placeholder)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configureUI(placeholder: String) {
let spacer = UIView()
spacer.setDimensions(height: 50, width: 12)
leftView = spacer
leftViewMode = .always
borderStyle = .none
textColor = .white
keyboardAppearance = .dark
backgroundColor = UIColor(white: 1, alpha: 0.1)
setHeight(50)
attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [.foregroundColor: UIColor(white: 1, alpha: 0.75)])
}
}
I was able to achieve the effect by wrapping the toolbar (chat input bar in my case) and constraining it top/right/left + bottom to safe area of the wrapper.
I'll leave an approximate recipe below.
In your view controller:
override var inputAccessoryView: UIView? {
keyboardHelper
}
override var canBecomeFirstResponder: Bool {
true
}
lazy var keyboardHelper: InputBarWrapper = {
let wrapper = InputBarWrapper()
let inputBar = InputBar()
helper.addSubview(inputBar)
inputBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
inputBar.topAnchor.constraint(equalTo: helper.topAnchor),
inputBar.leftAnchor.constraint(equalTo: helper.leftAnchor),
inputBar.bottomAnchor.constraint(equalTo:
helper.safeAreaLayoutGuide.bottomAnchor),
inputBar.rightAnchor.constraint(equalTo: helper.rightAnchor),
])
return wrapper
}()
Toolbar wrapper subclass:
class InputBarWrapper: UIView {
var desiredHeight: CGFloat = 0 {
didSet { invalidateIntrinsicContentSize() }
}
override var intrinsicContentSize: CGSize {
CGSize(width: 0, height: desiredHeight)
}
required init?(coder aDecoder: NSCoder) {
fatalError()
}
override init(frame: CGRect) {
super.init(frame: frame);
autoresizingMask = .flexibleHeight
backgroundColor = UIColor.systemGreen.withAlphaComponent(0.2)
}
}

Custom navigation bar items improperly placed

I have a custom navigation bar subclass:
class ProfileNavigationBar: UINavigationBar {
var titleLabel: UILabel
var backButton: UIBarButtonItem
var friendsButton: FriendsButton?
required init?(coder: NSCoder) {
titleLabel = UILabel(frame: CGRect(x: 0, y: 40, width: 320, height: 40))
backButton = UIBarButtonItem.backButton(nil, action: nil)
friendsButton = FriendsButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24))
super.init(coder: coder)
}
override func awakeFromNib() {
super.awakeFromNib()
let item = UINavigationItem()
item.titleView = titleLabel
item.leftBarButtonItem = backButton
item.hidesBackButton = true
let friendsItem = UIBarButtonItem(customView: friendsButton!)
item.rightBarButtonItems = [friendsItem]
pushItem(item, animated: false)
}
}
where the FriendsButton resizes itself when it's state property is changed.
Problem is that when the view is first loaded, it appears like this, with the back button and the FriendsButton right at the edge of the nav bar: (.loading state)
However, when I change the FriendsButton state to .add, it appears normally like this:
How can I fix this?
Here is the implementation of FriendsButton:
class FriendsButton: UIView {
var state: FriendsButtonState {
didSet {
style(selected: state)
}
}
var title: String = "" {
didSet {
set(title: title)
}
}
var font = UIFont.boldSystemFont(ofSize: 11)
private var imageView: UIImageView!
private var button: UIButton!
var loading: UIActivityIndicatorView!
init(frame: CGRect, state: FriendsButtonState = .loading) {
self.state = state
super.init(frame: frame)
backgroundColor = .yellow
let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
imageView = UIImageView(frame: CGRect(x: plusYValue*2, y: plusYValue, width: plusSize, height: plusSize))
imageView.contentMode = .scaleAspectFit
addSubview(imageView)
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
button = UIButton(frame: CGRect(x: plusYValue*3.5 + plusSize, y: 0, width: titleSize.width, height: frame.size.height))
addSubview(button)
loading = UIActivityIndicatorView(activityIndicatorStyle: .gray)
loading.center = center
addSubview(loading)
style(selected: state)
updateSize()
}
func addTarget(object: Any, selector: Selector) {
button.addTarget(object, action: selector, for: .touchUpInside)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func style(selected: FriendsButtonState) {
configureBorder(state: selected)
loading.startAnimating()
loading.isHidden = state != .loading
isHidden = false
switch state {
case .friends:
backgroundColor = .black
button.setTitleColor(.white, for: .normal)
imageView.image = #imageLiteral(resourceName: "friends-tick")
title = "Friends"
// ... + all other cases
}
self.updateSize()
}
private func configureBorder(state: FriendsButtonState) {
layer.borderColor = UIColor.black.cgColor
layer.borderWidth = state == .loading ? 0 : 1
layer.cornerRadius = 5
}
private func set(title: String) {
let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
button.titleLabel?.font = font
button.setTitle(title, for: .normal)
button.frame = CGRect(x: plusYValue*3.5 + plusSize, y: 0, width: titleSize.width, height: frame.size.height)
self.updateSize()
}
private func updateSize() {
if state == .loading {
frame.size.width = frame.size.width
loading.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2)
loading.startAnimating()
return
}
let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
let totalWidth = plusYValue*5.5 + plusSize + titleSize.width
frame.size.width = totalWidth
}
EDIT: I have tried setting the button to the .add state initially but it would still appear at the very right of the nav bar until it was changed to the other state. It seems that the first state of the button always make the nav bar to shift all its children to the edge of the frame until it is updated.
EDIT: I wasn't able to reproduce the problem on another project by copying the relevant code, but this is the specific problem I am having (shown in the image below). The gap between the edge of the navigation bar and the back button is not maintained when first navigating to the view (I managed to get a screenshot midway through the navigation push animation). My question is now, what could be causing this?
You'll have to stop the activity indicator, otherwise it won't hide itself:
private func style(selected: FriendsButtonState) {
configureBorder(state: selected)
if (state == .loading) {
loading.startAnimating()
} else {
loading.stopAnimating()
}
loading.isHidden = state != .loading
Btw: You could also skip loading.isHidden = state != .loading if you configure the UIActivityIndicatorView as to hide itself when its stopped:
init(frame: CGRect, state: FriendsButtonState = .loading) {
// ...
loading = UIActivityIndicatorView(activityIndicatorStyle: .gray)
loading.center = center
loading.hidesWhenStopped = true
addSubview(loading)
// ...
}
To lay out the right navigation bar button correctly, you have to modify FriendsButton.updateSize: When in state .loading - at least for the first time - you also have to update the frame.
private func updateSize() {
if state == .loading {
frame.size.width = frame.size.width
loading.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2)
loading.startAnimating()
// do not return here
}
let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
let totalWidth = plusYValue*5.5 + plusSize + titleSize.width
frame.size.width = totalWidth
}
I assume the same for the left button, but unfortunalty the your code does not compile here (get an error in the init? method when calling backButton = UIBarButtonItem.backButton(nil, action: nil), because there is no static member backButton on UIBarButtonItem
Now, it works on my machine:
Just after start of the app:
After state change to .friends
State changed back again to .loading
Everything is well aligned, no changes etc.
If this does not hold true for your project, than there might be other aspects that you didn't publish with your code.
You should update the frames of the subviews in layoutSubviews(), so you should override this method. The layoutSubviews() method is called whenever the frame changes and when the layout is flagged as being 'dirty' (by calling setNeedsLayout() you can achieve this).
It looks like you want to set the FriendsButtonState of the friendsButton in the init. Change:
friendsButton = FriendsButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24))
to
friendsButton = FriendsButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24), state:.add)

Dismissing of search bar

I have some problem. I have UITableView and header of tableView is searchController with 1 red view (Inside of this view will be some icon).
After staring of search appears cancel button.
And now I press cancel button and search bar resize to full screen size and red view is disappear.
How to solve this problem?
Here is my headerView class:
lazy var searchController = UISearchController(searchResultsController: nil).then {
//return UISearchController().then {
$0.dimsBackgroundDuringPresentation = false
$0.searchBar.placeholder = "Искать по имени"
$0.searchBar.tintColor = .black
$0.searchBar.searchBarStyle = .minimal
$0.searchBar.backgroundColor = .white
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes([NSFontAttributeName : UIFont.appleSystemRegular(15)], for: .normal)
$0.searchBar.setValue("Отмена", forKey:"_cancelButtonText")
}
lazy var contentView: UIView = {
let view = UIView()
view.backgroundColor = .red
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupConstrains()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
fileprivate func setupViews() {
addSubview(contentView)
addSubview(searchController.searchBar)
}
func setupConstrains() {
searchController.searchBar.frame = CGRect(x: 0, y: 0, width: self.frame.width - 80, height: 44)
contentView.frame = CGRect(x: self.frame.width - 65, y: 0, width: 50, height: 44)
}
Remove searchcontroller and try to search only searchbar delegate.
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
}

Xcode 7.3.1 : Set background image to UINavigationBar and display back button

I want to set logo of app as background image to UINavigationBar and when user traverse into app it should display logo as well as back button on top of it.
Below is code that I've used :
func setNavigationBar() {
let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height
let screenSize: CGRect = UIScreen.mainScreen().bounds
let objCustomView = CustomView(frame: CGRect(x: 0, y: 0, width: screenSize.width, height: navigationBarHeight))
let objWindow = UIApplication.sharedApplication().keyWindow
objWindow?.addSubview(objCustomView)
self.navigationItem.setHidesBackButton(false, animated:true);
self.navigationItem.backBarButtonItem = UIBarButtonItem(title:"", style:.Plain, target:nil, action:nil)
}
The issue with this is that back button goes behind the image.
How to fix this?
After refering post by #NDoc I'm getting extra space in left. Why so?
Also, the back button should be white with no back text i.e. only < arrow.
Below is code for customView :
class CustomView: UIView {
var imgLogo = UIImageView(frame:CGRectZero)
override init(frame: CGRect) {
super.init(frame: frame)
let screenSize: CGRect = UIScreen.mainScreen().bounds
imgLogo.frame = CGRectMake(0, 0, screenSize.width, 44.0)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup() {
imgLogo.image = UIImage(named:"BoM_Logo")
self.addSubview(imgLogo)
}
}
You can display your logo in leftBarButtonItem and set the leftItemsSupplementBackButton to true to display backButton also like this.
let logoView = UIImageView(frame: CGRect(x: 0, y: 0, width: 60, height: 30))
logoView.image = UIImage(named: "Logo")
let item = UIBarButtonItem(customView: logoView)
self.navigationItem.leftBarButtonItem = item
To show the back button with your logo image set leftItemsSupplementBackButton to true
self.navigationItem.leftItemsSupplementBackButton = true
Edit:
If you want custom arrow then you need to use leftBarButtonItems and pass array of BarButtonItem and no need to set leftItemsSupplementBackButton to true like this.
let logoView = UIImageView(frame: CGRect(x: 0, y: 0, width: 60, height: 30))
logoView.image = UIImage(named: "Logo")
let logoItem = UIBarButtonItem(customView: logoView)
let btnBack = UIButton(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
btnBack.setImage(UIImage(named: "Back_Arrow"), forState: .Normal)
btnBack.addTarget(self, action: #selector(self.buttonAction(_:)), forControlEvents: .TouchUpInside)
let backItem = UIBarButtonItem(customView: btnBack)
self.navigationItem.leftBarButtonItems = [backItem, logoItem]
Note: Don't forgot to add buttonAction action method inside your viewController.
Try this in your appDelegate
let image = UIImage.init(named:"upper-bar.png")
UINavigationBar.appearance().setBackgroundImage(image,forBarMetrics:UIBarMetrics.Default)
for back button try this in the viewDidLoad() of your viewController
let image1 = UIImage(named: "go10.png") as UIImage?
let btnLeft = UIButton(type: .Custom)
btnLeft.frame = CGRectMake(0, 0, 25, 25)
btnLeft.setImage(image1,forState:UIControlState.Normal)
btnLeft.addTarget(self, action:(#selector(NameofyourViewController.backBtn(_:))),forControlEvents:UIControlEvents.TouchUpInside)
let leftBarButton = UIBarButtonItem(customView: btnLeft)
self.navigationItem.leftBarButtonItem = leftBarButton
#IBAction func backBtn(sender: UIButton)
{
self.navigationController?.popViewControllerAnimated(true)
}

Resources