Using a UIButton into Navigation Bar using StoryBoard - ios

Essentially I have a UIButton created in StoryBoards that I would like to drag into the navigation bar. This UIButton has an action associated with it when touched but all touch events stop working when I drag this UIButton into the navigation bar.
Is there additional code I need to the IBAction item when doing this?
One of the main reasons I want to add a UIButton instead of a BarButtonItem to the navigation bar is simply because it allows me to add a background color and curve the edges of the button.

I don't think you can do it in the storyboard. You have to do it in code, using the init(customView:) initialiser.
let myCustomButtonWithBackgroundsAndStuff = UIButton(type: .custom)
...
// this is the equivalent of connecting the IBAction, in code form, in case you didn't know
myCustomButtonWithBackgroundsAndStuff.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
let barButtonItem = UIBarButtonItem(customView: myCustomButton)
navigationItem.rightBarButtonItem = barButtonItem
// or append to rightBarButtonItems if you have other bar button items
...
#objc func buttonAction() {
...
}

Related

Unable to press UIButton underneath NavigationBar?

I have an app where there is a navigation controller which can have navigation child. I have to put a UIButton where the navigation bar is normally.
The UIButton is connected to targets:
for button in arrayOfButtons {
button.addTarget(self, action: #selector(buttonTouchUpInsideP3), for: [.touchUpInside])
button.addTarget(self, action: #selector(buttonTouchInsideBoundsP3), for: [.touchDown, .touchDragEnter])
button.addTarget(self, action: #selector(buttonDraggedOutOfBoundsP3), for: [.touchDragExit, .touchCancel]) //there is definitly combining that cud be done here...
}
And basically I can't simply hide the navigationBar as I use it for sizing/autolayout, so what I try to do is: (this code is in the ViewDidLoad of the child navigation controller)
self.navigationController?.navigationBar.isUserInteractionEnabled = false
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
self.navigationItem.hidesBackButton = true
To remove its UI and have it invisible up there, this part works... however, the issue is that I still cannot press anything in the navigationBar area... even though I do isUserInteractionEnabled = false.
How can I fix this!? So that I can tap a UIButton underneath(?) or rather where the navigationBar is located??
Haven't seen a SO question that has solved this for me :/
Well, for anyone that wants to know:
#StonedStudio was right, I ended up just hiding the navigation bar and instead I simply created a view with the bounds height of the navigationBar anchored to the top of the view.safeAreaLayoutGuide.topAnchor and that way it takes the shape of the would be navigation bar while allowing the tap as well! :)

How to drop an object on a bar button item?

I've got this collection view, and I want to be able to delete a cell by dragging it in the trash bar button on the right of the bar.
I don't understand how to make the button able to receive a drop,
if it was a UIView I can do
addInteraction(UIDropInteraction(..))
but since it is a button I can't act this way.
Someone can help me?
You can try creating a custom view and add interactions to it. And finally, add that to the rightBarButtonItem. Something on the lines of:
func viewDidLoadForBarButton() {
let customView = UIView() //Add your custom UIView() here
customView.sizeToFit()
let dropInteraction = UIDropInteraction(delegate: self)
customView.addInteraction(dropInteraction)
let barButton = UIBarButtonItem(customView: customView)
self.navigationItem.rightBarButtonItem = barButton
}
Let me know if it works.

Navigation bar error

I've embed in the navigation bar in app, everything work good, except when entering a view where I have set up the navigation bar programmatically (segue to settings, reset function).
It shows just the custom navigation bar, which is ok, but if I implement a custom back button, the whole app has the same navigation bar as problematic one (now it shows the reset and settings button everywhere).
Is there a way to make the navigation bar custom only to that specific view?
Part of the code:
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
//Add gesture to MainLabel
let tapLabel: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(resetTime))
tapLabel.delegate = self
mainLabel.isUserInteractionEnabled = true
mainLabel.addGestureRecognizer(tapLabel)
//Add gesture to UINavigationBar title
let tapTitle: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(resetTime))
tapTitle.delegate = self
self.navigationItem.titleView = resetLabel
self.navigationItem.titleView?.isUserInteractionEnabled = true
self.navigationItem.titleView?.addGestureRecognizer(tapTitle)
}
yes, you can hide navigation button on viewDidDisappear of a viewController in which you want custom navigation bar and in viewDidAppear unhide buttons which you need.

SWRevealViewController with NavigationController - Swift 3

I want to make an app in which my navigation bar appears on all pages. When I click on any row of side menu(done through SWRevealViewController), I want the page that opens to have a navigation bar on top. In the image below, I want the same navigation bar as the HomeViewController on the page that has "Menu" label. How can I do this? Please help. I am new to iOS. I am doing this in Xcode 8 and Swift 3.
EDIT : I want something like this: I have placed the side menu button on the reveal view controller. I can see it on the front view controller at runtime but how to connect the target and action of revealviewcontroller then, so that the side menu opens? If this is done then my problem of navigation controller on "Menu" label page will be solved automatically
Suppose outlet of menu is btn_Menu. In controller's view did load I set bar button's action and target programmatically.
btn_Menu.target = self.revealViewController()
btn_Menu.action = #selector(SWRevealViewController.revealToggle(_:))
Have a look at this image structure that you need. Sorry not very clear but perhaps solve your issue:
You need to add all the starting points of your ViewControllers in a NavigationController of their own so in this case you need to embed the ViewController which has the menu label in a NavigationController and make the side menu segue to the NavigationController not the ViewController
hope my answer helps you
1) create a new ViewController Class called 'BaseViewController'
2) in the BaseViewController viewDidLoad add the following code and change the images names and targets also add the left button for the menu
let btn1 = UIButton(type: .custom)
btn1.setImage(UIImage(named: "imagename"), for: .normal)
btn1.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
btn1.addTarget(self, action: #selector(Class.Methodname), for: .touchUpInside)
let item1 = UIBarButtonItem(customView: btn1)
let btn2 = UIButton(type: .custom)
btn2.setImage(UIImage(named: "imagename"), for: .normal)
btn2.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
btn2.addTarget(self, action: #selector(Class.MethodName), for: .touchUpInside)
let item2 = UIBarButtonItem(customView: btn2)
self.navigationItem.setRightBarButtonItems([item1,item2], animated: true)
3) make the viewControllers which you will show from the side menu like the one with menu label inherits from BaseViewController and in it's viewDidLoad make it call super.viewDidLoad()
4) embed the viewControllers which you will show from the side menu in a navigationController
Using Container View may help.
Replace the UIView in the middle (Content) with a Container View and that container can be a UINavigationController. And to avoid having 2 NavigationBars you can hide the NavigationBar of the ContainerView.
The blue highlighted view is the ContainerView inside the Controller that is implementing SideMenu
You also need to add Navigation Controller for sabe bar Controller
Follow the steps :
Select side bar viewcontroller > go to Editior menu > Embed in > Click Navigation Controller

How do i add a cancel on a navigation bar?

My goal is to add a cancel bar item on a navigation bar. The scenario is a user presses the button then it will segue modally to another UIView Controller and there will be a cancel button. The cancel button will bring the use back to the first screen
Example
what I did currently is drag a navigation bar onto UIViewController, it works but when I try to drag bar item onto the navigation bar, it doesn't work. What am I missing right now?
Add UIBarButtonItem in navigation bar programmatically
let btnCancel = UIButton()
btnCancel.setImage(UIImage(named: "crossbuttonimagename"), forState: .Normal)
btnCancel.frame = CGRectMake(0, 0, 25, 25)
btnCancel.addTarget(self, action: Selector("youraction"), forControlEvents: .TouchUpInside)
//Set Left Bar Button item
let leftBarButton = UIBarButtonItem()
leftBarButton.customView = btnCancel
self.navigationItem.leftBarButtonItem = leftBarButton
Embed your Second View controller into a Navigation Controller.
Present modally this Navigation Controller.
Drag & Drop an UIBarButton Item (X button) to the Navigation Bar in the Second View Controller.
Create an action to go back to First View Controller.
#IBAction func actionDismiss(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
Assign this action to the Cancel Button.
Select the segue which leads to the problematic view controller
Set that to PUSH segue
Again unselect the PUSH segue and now accepted SHOW segue
After these step you can add right bar button item using storyboard.

Resources