I'm trying to setup the custom navigation bar in my iOS app, but .frame = CGRect(...) doesn't change the size of buttons that I added to it. Buttons appeared inside the navigation bar, but they have wrong size, or maybe constraints, I don't know.
// Setting up the Navigation Bar
private func setupNavigationBar() {
// Remove the shadow under the Navigation Bar
self.navigationController?.navigationBar.shadowImage = UIImage()
let addButton = UIButton(type: .system)
addButton.setImage(UIImage(named: "ic_add")?.withRenderingMode(.alwaysOriginal), for: .normal)
addButton.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
let settingsButton = UIButton(type: .system)
settingsButton.setImage(UIImage(named: "ic_settings")?.withRenderingMode(.alwaysOriginal), for: .normal)
settingsButton.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
navigationItem.rightBarButtonItems = [UIBarButtonItem(customView: settingsButton), UIBarButtonItem(customView: addButton)]
}
(I call this function inside the viewDidLoad())
Here you can see the result on my iPhone:
This is work for me. Please try it. (iOS 11)
private func setupNavigationBar() {
// Remove the shadow under the Navigation Bar
self.navigationController?.navigationBar.shadowImage = UIImage()
let addButton = UIButton(type: .custom)
addButton.setImage(UIImage(named: "ic_add")?.withRenderingMode(.alwaysOriginal), for: .normal)
addButton.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
let settingsButton = UIButton(type: .custom)
settingsButton.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
settingsButton.setImage(UIImage(named: "ic_settings")?.withRenderingMode(.alwaysOriginal), for: .normal)
let menuBarItem = UIBarButtonItem(customView: settingsButton) // new line
let currWidth = menuBarItem.customView?.widthAnchor.constraint(equalToConstant: 10) // new line
currWidth?.isActive = true // new line
let currHeight = menuBarItem.customView?.heightAnchor.constraint(equalToConstant: 10) // new line
currHeight?.isActive = true // new line
navigationItem.rightBarButtonItems = [
menuBarItem, // modify
UIBarButtonItem(customView: addButton)]
}
Try to change the button type
Replace .system to .custom .
Also check the size of original image if it is very large.
Related
I follow a video from youtube. And i ran into a problem when ı try to set Navigation Controller items.
func setupNavigationBarItems() {
let twitterImage = UIImageView(image: UIImage(named: "twitter_icon"))
twitterImage.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
twitterImage.contentMode = .scaleAspectFit
navigationController?.navigationItem.titleView = twitterImage
let profileButton = UIButton(type: .system)
profileButton.setImage(UIImage(named: "profile_image"), for: .normal)
profileButton.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
navigationController?.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: profileButton)
}
Result
This is the result. Nothing show up
Edit--
I made same changes
navigationController?.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: profileButton)
--
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: profileButton)
it just shows the profileButton and button stretches all over to the edges
new result
Click on debug view
will help you to debug what going on with your view
(Build Project first and you will see this button)
let SearchView = UIView()
SearchView.backgroundColor = UIColor.clear
SearchView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
let Searchbutton = UIButton(type: .system)
Searchbutton.setImage(UIImage (named: "SEARCH"), for: .normal)
Searchbutton.backgroundColor = .clear
Searchbutton.frame = CGRect(x: -17, y: -20, width: 30, height: 30)
Searchbutton.contentMode = .scaleAspectFit
let WidthConstraint = Searchbutton.widthAnchor.constraint(equalToConstant: 30)
let HeightConstraint = Searchbutton.heightAnchor.constraint(equalToConstant: 30)
WidthConstraint.isActive = true
HeightConstraint.isActive = true
let barButtonItem = UIBarButtonItem(customView: SearchView)
self.navigationItem.rightBarButtonItem = barButtonItem
SearchView.addSubview(Searchbutton)
Searchbutton.addTarget(self, action: #selector(viewanewcontroller(button:)), for: .touchUpInside)
//right search button
After making a button, I wanted to move it little bit to the right. So, i made UI View to move the button inside the view. But, then, after this, the button does not work anymore. Can anyone tell me the solution?
Your code is working fine but need to clarify some points.
Reason Your button not working is below 4 lines
let WidthConstraint = Searchbutton.widthAnchor.constraint(equalToConstant: 30)
let HeightConstraint = Searchbutton.heightAnchor.constraint(equalToConstant: 30)
WidthConstraint.isActive = true
HeightConstraint.isActive = true
As you already set UIButton frame then no need to use of above lines of code.
Yellow color view is your SearchView and green color is your UIButton.
If you use Searchbutton frame like Searchbutton.frame = CGRect(x: -17, y: -20, width: 30, height: 30) then it happens something like below image.
You added UIButton as subview of UIView and when you click on green button which is inside yellow View will work but the area which is outside Yellow area doesn't work.
You need to start UIButton frame from 0,0,30,30
Searchbutton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
or you can directly set UIButton frame same as UIView frame then it looks like below image.
Searchbutton.frame = SearchView.frame
Below is your Working Code.
let SearchView = UIView()
SearchView.backgroundColor = UIColor.clear
SearchView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
let Searchbutton = UIButton(type: .system)
Searchbutton.setImage(UIImage (named: "SEARCH"), for: .normal)
Searchbutton.backgroundColor = .clear
Searchbutton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
Searchbutton.contentMode = .scaleAspectFit
let barButtonItem = UIBarButtonItem(customView: SearchView)
self.navigationItem.rightBarButtonItem = barButtonItem
SearchView.addSubview(Searchbutton)
Searchbutton.addTarget(self, action: #selector(viewanewcontroller(button:)), for: .touchUpInside)
//right search button
You're doing a lot of unnecessary things here. Firstly, you don't need to put your Button in a container view to put it as the right bar button item.
You also don't need to add constraints to your searchbutton, since you have given it a fixed frame.
let Searchbutton = UIButton(type: .system)
Searchbutton.setImage(UIImage (named: "SEARCH"), for: .normal)
Searchbutton.backgroundColor = .clear
Searchbutton.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
Searchbutton.contentMode = .scaleAspectFit
let barButtonItem = UIBarButtonItem(customView: Searchbutton)
self.navigationItem.rightBarButtonItem = barButtonItem
Searchbutton.addTarget(self, action: #selector(viewanewcontroller(button:)), for: .touchUpInside)
Also as Pratik's comment said, you're meant to use lower camel case. so SearchView should be searchView and SearchButton as searchButton
As for moving it to the right, it seems like that isn't possible anymore without either subclassing the UINavigationBar and changing the implementation, or by making UIViews look exactly like the standard Navigation Bar.
Get rid of the space on the right side of a UINavigationBar
The function self.navigationItem.rightBarButtonItem = cartBarButton won't show my item on the right of UINavigationController's NavBar
EDIT
let cartOriginalImage = UIImage.cart
let cartButton = UIImageButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
cartButton.setBackgroundImage(cartOriginalImage, for: .normal)
cartButton.tintColor = Colors.Navigation.Tint.default
cartButton.addTarget(self, action: #selector(MainViewController.cartButtonPressedInHomePage(sender:)), for: .touchUpInside)
let cartBarButton = UIBarButtonItem(customView: cartButton)
if let badge = badge {
cartBarButton.badgeValue = badge
cartBarButton.badge.backgroundColor = Colors.Navigation.Background.badge
cartBarButton.badge.textColor = Colors.Navigation.Text.badge
}
I had the similar issue with custom image view. My suggestion is to wrap your custom view into container view.
private func configureUserAvatarView() {
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(avatarViewAction(_:)))
let customView = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
customView.addGestureRecognizer(tapRecognizer)
let imageView = FUIImageView(image: #imageLiteral(resourceName: "avatar_default_30х30"))
imageView.isCircular = true
imageView.contentMode = .scaleAspectFit
imageView.frame = customView.bounds
customView.addSubview(imageView)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: customView)
}
//This is my custom navigation function
func addSlideMenuButton()
// This is my custom navigation bar
let navigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width,height: 104))
let backgroundImage = UIImage(named: "BarBa")?.resizableImage(withCapInsets: UIEdgeInsetsMake(0, 15, 0, 15), resizingMode: UIImageResizingMode.stretch)
UINavigationBar.appearance().setBackgroundImage(backgroundImage, for: .default)
// Create a navigation item with a title
let navigationItem = UINavigationItem()
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 70, height: 90 ))
imageView.contentMode = .scaleAspectFit
let image = UIImage(named: "logo.png")
imageView.image = image
navigationItem.titleView = imageView
let button = UIButton.init(type: .custom)
button.setImage(UIImage.init(named: "sidebar.png"), for: UIControlState.normal)
button.addTarget(self, action:#selector(NewsTableViewController.callMethod), for: UIControlEvents.touchUpInside)
button.frame = CGRect.init(x: 0, y: 0, width: 70, height: 80)
let customBarItem = UIBarButtonItem(customView: button)
self.navigationItem.leftBarButtonItem = customBarItem;
navigationBar.items = [navigationItem]
// Make the navigation bar a subview of the current view controller
self.view.addSubview(navigationBar)
//tapping the menu button work
// Here revealViewController is a objective C class
if self.revealViewController() != nil {
button.target = self.revealViewController()
button.action = #selector(SWRevealViewController.revealToggle(_:)) // in this 2 line i got error cannot assign to the property "target is a method"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
// for set customiz width
self.revealViewController().rearViewRevealWidth = 250
}
// Assign the navigation item to the navigation bar
navigationBar.items = [navigationItem]
self.view.addSubview(navigationBar)
}
I guess this is what you are looking for and target & action are methods. you are treating it like properties. and i'm guessing self.revealViewController() returning SWRevealViewController instance.
button.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
Working code
menuButton.addTarget(self.revealViewController(), action:
#selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
you are not using a bar button item, SWRevealController action and target work with bar button not simple button
I saw the answer for this question for adding an image to the left nav bar item. And I did it successfully.
But I also want to add a small text next to the image. For example I want to show how many coins the user have. So I need to show a coins image and the number of coins next to it. How can it be done?
I tried to set title (with "123"), but I only see the image and not the title. This my code:
let button = UIButton.init(type: .custom)
button.setImage(UIImage.init(named: "coins.png"), for: UIControlState.normal)
button.addTarget(self, action:#selector(self.callMethod), for: UIControlEvents.touchUpInside)
button.frame = CGRect.init(x: 0, y: 0, width: 30, height: 30)
button.setTitle("123", for: UIControlState.normal)
let barButton = UIBarButtonItem.init(customView: button)
self.navigationItem.leftBarButtonItem = barButton
Thanks.
Since the bar button item is initialized with a custom view, you can add a UIImage and a UILabel to one view, along with a UIButton to capture the touch event, and pass that into the initializer.
// the UIButton is simply there to capture touch up event on the entire bar button view.
let button = UIButton.init(type: .custom)
button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
imageView.image = UIImage(named: "coins")
let label = UILabel(frame: CGRect(x: 35, y: 0, width: 50, height: 30))
label.text = "1234"
let buttonView = UIView(frame: CGRect(x: 0, y: 0, width: 90, height: 30))
button.frame = buttonView.frame
buttonView.addSubview(button)
buttonView.addSubview(imageView)
buttonView.addSubview(label)
let barButton = UIBarButtonItem.init(customView: buttonView)
self.navigationItem.leftBarButtonItem = barButton
You might have to adjust the frames accordingly for your own uses, of course.
I think your problem is the width it's 30 try to make it bigger like 50
let buttonContainer:UIView = UIView()
buttonContainer.frame = CGRect(x: 0, y: 0, width: 50, height: 32)
let image = UIImage(named: "coins")
let button = UIButton.init(type: .system)
button.setImage(image, for: .normal)
button.frame = buttonContainer.frame
button.setTitle("sss", for: .normal)
button.addTarget(self, action: #selector(action(_:)), for: .touchUpInside)
buttonContainer.addSubview(button)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: buttonContainer)
You can use backgroundImage for image and setTitle for test to the button.
follow this link definitely you will get idea:
image for nav bar button item swift
Use self.navigationItem.leftBarButtonItems that is an array of UIBarButtonItem
let button = UIBarButtonItem()
let text = UIBarButtonItem()
self.navigationItem.leftBarButtonItems = [button, text]