I have a UIButton. I bound a target as follows.
[button addTarget:self action:#selector(myFunction)
forControlEvents:UIControlEventTouchUpInside];
When i click my Button multiple times quickly it invoke the target function multiple times.
On Tapping button i present a new View controller.
when i click 3 times quickly then my new view controller is shown 3 times.
This is something stupid. Whats the point of triggering the function again once the View has been shifted to a new View controller. Why the Hell Apple do such stupid things ?
Any Help please?
First of all its not apple bugs. It should be handle manually. So follow these step
First make your global instance of your button then do this
.h file
#property (weak, nonatomic) IBOutlet UIButton *btn;
.m file
- (IBAction)myFunction:(id)sender
{
self.btn.userInteractionEnabled = NO;
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.btn.userInteractionEnabled = YES;
}
Take one global bool flag like "isItDone" or it declare in singleton class.
in "myFunction" set it as false
which View controller you push on that function in that class's "ViewDidAppear" method set as true.
it will help you.
I have same problem and it is good solution for that to manage it using one global variable.
I think this will help you.
Change your calling function like this
- (IBAction)myFunction:(id)sender
{
UIButton *button = (UIButton*)sender;
button.userInteractionEnabled = NO;
}
and call your function like this
[button addTarget:self action:#selector(myFunction:)
forControlEvents:UIControlEventTouchUpInside];
if you want to store the selection incase you came back to the view controller then only you need to keep a boolean flag to store if its clicked once or not.
Set the IBOutlet to your button, in the viewWillAppear method write,
button.userInteractionEnabled = YES;
and when you click on the button set,
button.userInteractionEnabled = NO;
I have a record button, which when pressed, I want to hide the instructions button.
Here's the code for the record button:
// Create custom overlay
// Create instruction/record button
// Add instruction/record button to custom overlay
[_videoRecordBtn addTarget:self action:#selector(startVideoRecord:) forControlEvents:UIControlEventTouchUpInside];
So in startVideoRecord I should have something like:
-(IBAction)startVideoRecord:(id)sender{
[_instru setHidden:YES];
// start recording...
}
But I have no idea how to pass the _instru button over to startVideoRecord.
Add a property to your ViewController to keep a reference to your instructionsButton:
#property (nonatomic, strong) UIButton *instructionsButton;
When you create your instructionsButton, assign it to this property.
Then you can access the button via this property anywhere in your ViewController with self. instructionsButton.
So, your action method would be like:
-(IBAction)startVideoRecord:(id)sender{
self.instructionsButton.hidden = YES;
// start recording...
}
You can do this by 2 way..
1 way - > you set the tag of instructions button.
and use this
-(IBAction)startVideoRecord:(id)sender{
UIButton *instruBtn = (UIButton*)[self.view viewWithTag:your button tag];
instruBtn.hidden = YES;
// start recording...
}
2nd Way - > you make property for your instructions button and use like this
-(IBAction)startVideoRecord:(id)sender{
self.instruBtn.hidden = YES;
// start recording...
}
I'm stumped at why this code isn't working. I have a login button that I want to disable when the user isn't logged in.
I have a UIButton delared in my .h file like so:
IBOutlet UIButton *myBtn;
I've set up a referencing outlet in Interface Builder to this button.
In my .m file, I've tried:
[myBtn setEnabled: NO];
and
myBtn.enabled = NO;
But neither of these disable the button in the conditional statement I'm in. (I want to disable the login button when the user successfully logs in)
I'm able to do this with two other buttons on the same screen, so I know the code is correct. I don't throw any errors, so I think the object exists. The references to myBtn change color in XCode, too, so it appears to be a valid reference.
I must be missing something. What am I doing wrong here? (I'm a Windows developer, relatively new at Objective-C)
It seems ok to me. Are you synthesizing the button? Try
self.myBtn.enabled = NO;
If you're looking for Swift3 solution
var myBtn = UIButton()
myBtn.isEnabled = true
You should be setting up your button as a IBOutlet.
#property (weak, nonatomic) IBOutlet UIButton *myBtn;
That way you can connect that button in storyboards. Which could be your issue.
Then call this to disable.
[_myBtn setEnabled:NO];
Do try this ..
In .h :
#property(nonatomic,retain)UIButton *myBtn;
In .m :
#synthesize myBtn;
And then,replace your [myBtn setEnabled: NO]; code with [self.myBtn setEnabled: NO]; code.
If you are looking for swift code:
var button = UIButton()
button.enabled = false //disable the button
i have a Navigation Bar, wich contains a Navigation Item, which contains 2 Bar Buttons, these are created in the Storyboard, and i wanted to change 1 of the buttons at runtime, now this works:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UINavigationItem *thisNavBar = [self myNavigationItem];
thisNavBar.rightBarButtonItem = nil; // this works, it gets removed
UIBarButtonItem *insertBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(insertSkemaItem:)];
thisNavBar.rightBarButtonItem = insertBtn; // this also works, it sets the btn
}
Now, in my other method, which is called by another controller, it does not work
- (void)callChildChange {
...
// remove old btn
UINavigationItem *thisNavBar = [self skemaNavigationItem];
thisNavBar.rightBarButtonItem = nil; // does not work?
}
There is nothing wrong with the method, it runs just fine, but the nav btn item does not get removed ?
skemaNavigationItem is a Navigation item, declared in the .h file which links the navigation item i made via the storyboard.
Your UI items need to be added to your code (by ctrl-dragging) in the header file (.h) so they can be publicly accessed from other classes/view controllers.
Presuming you've done this, hiding a UI item is best done by using
relevantClass.yourViewObject.hidden = YES;
or if you really need to delete it for good,
[relevantClass.yourViewObject.view removeFromSuperView];
Edits
Options for changing target method:
Declare #property (nonatomic, assign) BOOL myButtonWasPressed; and:
- (IBAction) myButtonPressed
{
if (!self.myButtonWasPressed)
{
// This code will run the first time the button is pressed
self.myButton.text = #"New Button Text";
self.myButtonWasPressed = YES;
}
else
{
// This code will run after the first time your button is pressed
// You can even set your BOOL property back, and make it toggleable
}
}
or
- (IBAction) myButtonWasPressedFirstTime
{
// do what you need to when button is pressed then...
self.myButton.text = #"New Button Text";
[self.myButton removeTarget:self action:#selector(myButtonPressedFirstTime) forControlEvents:UIControlEventTouchUpInside];
[self.myButton addTarget:self action:#selector(myButtonPressedAgain) forControlEvents: UIControlEventTouchUpInside];
}
- (IBAction) myButtonWasPressedAgain
{
// this code will run the subsequent times your button is pressed
}
I need to hide the right button in the Navigation Bar, then unhide it after the user selects some options.
Unfortunately, the following doesn't work:
NO GOOD: self.navigationItem.rightBarButtonItem.hidden = YES; // FOO CODE
Is there a way?
Hide the button by setting the reference to nil, however if you want to restore it later, you'll need to hang onto a copy of it so you can reassign it.
UIBarButtonItem *oldButton = self.navigationItem.rightBarButtonItem;
[oldButton retain];
self.navigationItem.rightBarButtonItem = nil;
//... later
self.navigationItem.rightBarButtonItem = oldButton;
[oldButton release];
Personally, in my apps I make my nav buttons into #properties, so that I can trash & recreate them at will, so something like:
//mycontroller.h
UIBarButtonItem *rightNavButton;
#property (nonatomic, retain) UIBarButtonItem *rightNavButton;
//mycontroller.m
#synthesize rightNavButton;
- (UIBarButtonItem *)rightNavButton {
if (!rightNavButton) {
rightNavButton = [[UIBarButtonItem alloc] init];
//configure the button here
}
return rightNavButton;
}
//later, in your code to show/hide the button:
self.navigationItem.rightBarButtonItem = self.rightNavButton;
For Swift 3
if let button = self.navigationItem.rightBarButtonItem {
button.isEnabled = false
button.tintColor = UIColor.clear
}`
Set reference to nil:
current_controller_in_navcontroller.navigationItem.rightBarButtonItem = nil;
Also be sure to call this in the controller currently shown by the navController, not for the navController itself.
Show:
[self.navigationItem.rightBarButtonItem.customView setAlpha:1.0];
Hide:
[self.navigationItem.rightBarButtonItem.customView setAlpha:0.0];
You can even animate its showing/hiding
[UIView animateWithDuration:0.2 animations:^{
[self.navigationItem.rightBarButtonItem.customView setAlpha:1.0];
}];
If you have only one bar button item in the right side you can use this one,
self.navigationItem.rightBarButtonItem = nil;
Suppose if you have multiple bar button in the right side, for example suppose you have two bar button items(search button and filter button) in the right side of your navigation item. Now the right bar button items are
self.navigationItem.rightBarButtonItems = [searchItem,filterItem]
and you have to hide only search button, you can use like,
self.navigationItem.rightBarButtonItems = [filterItem]
Now what happening is, you can completely hide the search button from the navigation item and the filter item comes in the place of search item
Here's Matt's solution updated for Storyboards & ARC. Remember, IBOutlets are __weak by default, so you need to change that to strong for it not to be released too early.
#interface MAGTableViewController () <UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet UIBarButtonItem *rightBarButton;
#end
#implementation MAGTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationItem setRightBarButtonItem:nil];
}
- (IBAction)rightBarButtonItemTapped:(id)sender
{
[self.view endEditing:YES];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self.navigationItem setRightBarButtonItem:self.rightBarButton];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self.navigationItem setRightBarButtonItem:nil];
}
#end
Credit has to go to learner for this answer which the answer is from this question:
hide and show left navigation bar button on demand in iOS-7
This is the answer, which is far more simple.
//hide and reveal bar buttons
-(void) hideAndDisableLeftNavigationItem
{
[self.navigationItem.leftBarButtonItem setTintColor:[UIColor clearColor]];
[self.navigationItem.leftBarButtonItem setEnabled:NO];
}
-(void) showAndEnableLeftNavigationItem
{
[self.navigationItem.leftBarButtonItem setTintColor:[UIColor blueColor]];
[self.navigationItem.leftBarButtonItem setEnabled:YES];
}
Then you just reference the method where you require it like within an (IBAction) like so:
[self hideAndDisableLeftNavigationItem];//[self showAndEnableLeftNavigationItem]; to show again
I tried all other methods and none worked, even referencing my button as a #property (...) UIBarButtonItem.... and nothing worked until I found this.
SWIFT 2.2
In swift 2.2 self.navigationItem does not work. Instead create an outlet of the NavigationItem (I named it below "nav") and use it.
Also the following suggestion did not work for me using Xcode 7.3 and swift 2.2
nav.leftBarButtonItem?.customView?.hidden = true
So I used the idea of #Matt J above as follows (I have 2 items on the left):
Create outlets for the items in the navigation bar and variables to store them
#IBOutlet weak var settingItem: UIBarButtonItem!
#IBOutlet weak var logoItem: UIBarButtonItem!
var sav_settingItem: UIBarButtonItem = UIBarButtonItem()
var sav_logoItem: UIBarButtonItem = UIBarButtonItem()
Save the items in viewDidLoad()
sav_settingItem = nav.leftBarButtonItems![0]
sav_logoItem = nav.leftBarButtonItems![1]
To HIDE set them to nil
nav.leftBarButtonItem = nil
nav.leftBarButtonItem = nil
To SHOW them
if (nav.leftBarButtonItem == nil) {
nav.leftBarButtonItem = sav_settingItem
nav.leftBarButtonItems?.append(sav_logoItem)
return
}
Show:
[self.navigationItem.rightBarButtonItem.customView setHidden:NO];
Hide:
[self.navigationItem.rightBarButtonItem.customView setHidden:YES];
My solution:
self.navigationItem.rightBarButtonItem.customView.hidden=NO;
Swift 2:
Trick!
Hide:
if let btn = self.tabBarController!.navigationItem.rightBarButtonItem {
btn.enabled = false
btn.title = ""
}
Show:
if let btn = self.tabBarController!.navigationItem.rightBarButtonItem {
btn.enabled = true
btn.title = "ButtonName"
}
For swift 5 to hide rightBarButtonItem
self.navigationItem.rightBarButtonItem?.customView?.isHidden = true
In swift 4 I has a trick to show / hide right or left button:
Step 1: Create a IBOutlet button in view controller:
#IBOutlet var navigationItemButton: UIBarButtonItem!
Step 2: Create Hide button function:
func hideNavigationButton() {
navigationItemButton.isEnabled = false
navigationItemButton.tintColor = UIColor.clear
}
Step 3: Create Show button function:
func showNavigationButton() {
navigationItemButton.isEnabled = true
navigationItemButton.tintColor = UIColor.white
}
Step 4: Just call the functions that you want, use hideNavigationButton() to hide, and showNavigationButton() to show the button.
Regards!
You can use below code:
self.navigationItem.rightBarButtonItem?.image = nil
self.navigationItem.rightBarButtonItem?.isEnabled = false
Show:
//set navigationItem tint color white
self.navigationItem.rightBarButtonItem.tintColor = [UIColor whiteColor];
Hide:
//set navigationItem tint clear white
self.navigationItem.rightBarButtonItem.tintColor = [UIColor clearColor];
Assume you can reference the specific bar button as variable xxxButton
(please open Assistant Editor, Control+Drag xxx button to YourViewController class as outlet "xxxButton").
or you can use something like let xxxButton = navigationBar.buttons[1]
Hide
xxxButton.customView = UIView()
or
navigationItem.rightBarButtonItems?.remove(at: (navigationItem.rightBarButtonItems?.index(of:xxxButton)!)!)
Show
xxxButton.customView = nil
or
navigationItem.rightBarButtonItems?.insert(newElement: xxxButton, at:SOME_INDEX)
Hope helpful.
To hide:
if let topItem = self.navigationController?.navigationBar.topItem {
topItem.rightBarButtonItem = nil
}
Set the the title to empty first and after swlwction just set again.