iOS selector not getting called for UIBarButtonItem - swift

I've got some fairly simple code, and am trying to figure out why the uibarbuttonitem isn't triggering the selector:
TableView's viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
self.clearsSelectionOnViewWillAppear = false
// this line adds a button to top right
let addNewChecklistItemButton = UIBarButtonItem(barButtonSystemItem: .add,
target: nil,
action: #selector(self.addNewChecklistItemToDataModel))
self.navigationItem.rightBarButtonItem = addNewChecklistItemButton
}
Method called:
#objc func addNewChecklistItemToDataModel() {
print("adding new item...")
<...>
}
The button is being added (was not visible before I put this code in) and when I press it the button click animates but my console doesn't show the printed text.
After reading UIBarButtonItem selector not working, I'm wondering if the fact that my UITableViewController is embedded in both a UITabViewController and UINavigationViewController is effecting the button's scope? If not, anyone see something I'm missing?

Target shouldn't be nil
let addNewChecklistItemButton = UIBarButtonItem(barButtonSystemItem: .add,
target: self,
action: #selector(self.addNewChecklistItemToDataModel))

Related

dismiss keyboard after input

I am trying to build my first iOS app with swift 5.
I have a textfield where the user should type a value like 15,00
this is my result at the moment:
I searched for a solution to dismiss the keyboard.
Option 1: dismiss keyboard after user type a format like xx,xx
Option 2: a "Done" button im keyboard with decimal pad style
But I don't know, how I can realize any of this option.
Need help ! :)
You can add this code to your didLoad
var toolbar = UIToolbar()
toolbar.sizeToFit()
var flexibleSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
var doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: #selector(yourFunc))
toolbar.setItems([flexibleSpace, doneButton], animated: true)
yourTextField.inputAccessoryView = toolbar
When click done button you can do whatever you want but we want to do dismiss keyboard
#objc func doneClicked(){
searchBar.endEditing(true)
}

Adding a UIBarButtonItem programmatically

I'm trying to add a UIBarButtonItem programmatically.
let navigation = UINavigationController()
let rightBarButton = UIBarButtonItem(title: "LogIn", style: .plain, target: self, action: #selector(logInPressed))
navigation.navigationItem.rightBarButtonItem = rightBarButton
And also made a selector function for testing.
#objc func logInPressed() {
print("go to login")
}
Unfortunately that does not work - bar button is not visible on navigation bar in simulator.
Checked with a breakpoint, rightBarButtonItem exists.
Probably issue can be caused by creating bar button from app coordinator, not from child VC.
Could please anyone help to troubleshoot this issue?
Simulator screenshot
you are adding UIBarButtonItem to a new instance of NavigationController. so it will not appear there.
so in your view controller which you want to handle right navigation bar , under one of these methods:
override func viewDidLoad()
or
override func viewWillAppear
add:
let rightBarButton = UIBarButtonItem(title: "LogIn", style: .plain, target: self, action: #selector(logInPressed))
self.navigationController?.navigationItem.setRightBarButton(rightBarButton, animated: true)
Issue was caused by creating bar button not from child VC, but coordinator.
Bar buttons are stored in navigationItem property of UIViewController.

Adding Hamburger Button to SWRevealViewController in Swift

In the app I'm making I have a side menu that I used SWRevealViewController template to make. I made my own animated button to be the hamburger menu button so when its pressed the side menu will open. The problem is I can't figure out how to connect my animated button to the SWRevealViewController.
Here's the button code I made.
Animated Button
self.button = HamburgerButton(frame: CGRectMake(0, 0, 30, 30))
self.button.addTarget(self, action: #selector(home.toggle(_:)), forControlEvents:.TouchUpInside)
let refreshButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Refresh,
target: self, action: #selector(home.buttonMethod))
navigationItem.leftBarButtonItem = button
and heres the button that was used for the SWRevealViewController
override func viewDidLoad() {
super.viewDidLoad()
if revealViewController() != nil {
menuButton.target = revealViewController()
menuButton.action = #selector(SWRevealViewController.revealToggle(_:))
view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
}
Ive done a lot of research but just can't find out how to do it. I need the button I made, which is the first code, to be the one to access the SWRevealViewController and to open and close the side menu rather then the button, which is the second code, that came with the SWRevealViewController template. Any help will be Awesome!!
This is how I do it. You can adapt this to your needs.
let singleTap = UITapGestureRecognizer(target: self, action: #selector(tapDetected))
singleTap.numberOfTapsRequired = 1
sideMenuButton.userInteractionEnabled = true
sideMenuButton.addGestureRecognizer(singleTap)
func tapDetected() {
self.revealViewController().revealToggle(self)
}

How to create a plus symbol bar button item

How do you create UIBarButtonItem as a plus symbol? I tried giving it the title "+", but I would like it to look more like the plus symbol you would normally create if you used storyboard. Which doesn't have a background or an underline.
It's one of the provided bar button system items.
let addBarButton = UIBarButtonItem(barButtonSystemItem: .add, target: YOUR_TARGET, action: YOUR_SELECTOR)
I think this is what you are looking for:
Swift 4.2 Example
Here is how you do it:
let addBarButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addUser))
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = addBarButton
}
#objc private func addUser() {
// Some code, e.g.
let storyboard = UIStoryboard(name: "CreateNewUser", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "createUser") as! CreateUserVC
self.navigationController?.pushViewController(vc, animated: true)
}
IMPORTANT NOTE: There is a little problem though which many users have pointed out and took me many hours to figure out as well (for iOS 11, 12) that you must put the self.navigationItem.rightBarButtonItem = addBarButton inside the viewDidLoad function otherwise the button's selector won't work. This has something to do, as per other users on StackOverflow, with tap gestures. In my code, one of my view controllers have two buttons assigned outside of viewDidLoad function but there is also use a function to hide the keyboard, which probably causes the buttons to work fine. However, in view controllers of two other projects where I don't show or hide keyboard, the #selector for programatically set navigation bar buttons don't work unless they are defined within viewDidLoad function as in the example above. I hope this tip will save you tons of time in case you face this problem.
Swift 3.0
let addBarButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(ViewController.openSearch))

How to remove custom nav bar back button

I am adding some subview to main view controller. When I add one of these subview, I create a custom back button so that it will go back to main view controller, not the prior view controller in the navigation stack. I can add it programmatically but I can't seem to figure out how to delete it. Any help is greatly appreciated!
func createCustomBackButton() {
self.navigationItem.hidesBackButton = true
let customFont = UIFont.systemFontOfSize(26.0)
UIBarButtonItem.appearance().setTitleTextAttributes([NSFontAttributeName: customFont], forState: UIControlState.Normal)
// customBackButton is a property I set for UIBarButtonItem
customBackButton = UIBarButtonItem(title: "<", style: .Plain, target: self, action: "back:")
self.navigationItem.leftBarButtonItem = customBackButton
}
func back(sender: UIBarButtonItem) {
UIView.animateWithDuration(0.3, animations: {
self.containerView.alpha = 0
}, completion: { finished in
self.view.sendSubviewToBack(self.containerView)
self.navigationItem.hidesBackButton = false
// what do I do on this line to get this to disappear or set to nil??
self.customBackButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.z, target: self, action: nil)
// clears out prior view that was there to free up memory
for view in self.containerView.subviews {
view.removeFromSuperview()
}
})
}
Using self.navigationItem.leftBarButtonItem = nil will reset the leftBarButtonItem back to the default.
You should use an unwind segue. If you're using storyboards, drag from the "destination viewcontroller" to the thing that looks like a sideways share button (exit button) of the VC you want unwind from. Name it whatever you'd like, we'll call it "unwind"
and then call in the same VC:
self.performSegueWithIdentifier("unwind", sender: self)
in the VC you want to unwind back to:
#IBAction func unwindToMapSegue(segue: UIStoryboardSegue) {
// do something
}