Access UIButton in a category of a UIViewController - ios

I am creating a simple category of UIViewController which adds the possibility to show a button simply on top of the view to display a chat window.
#interface UIViewController (ChatButton)
- (void)showChatButtonFromTop;
- (void)showChatButtonFromBottom;
- (void)hideButton;
#end
Now in the method I create a button and display it:
- (void)showChatButtonFromTop
{
UIButton* chatBtn = [self constructButtonWithWidth:buttonAxisSize X:buttonX Y:buttonY];
[self.view addSubview:chatBtn];
}
But I also need to hide the button:
- (void)hideButton
{
// confusion!
}
How do I get that button? Categories don't allow for properties, so how do I store the reference?

when you add the button to view, add a tag to button
chatBtn.tag = 1234;
[self.view addSubview:chatBtn];
when you try to hide the button access it's tag
- (void)hideButton
{
UIButton *chatBtn = (UIButton *)[self.view viewWithTag:1234];
[chatBtn setHidden:YES];
}

Related

Hide a UIbutton when another UIbutton is pressed

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...
}

Issues with UINavigationItem changing properties at runtime

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
}

Two actions for one UIBarButtonItem?

I have an edit button, that I obtained through self.editButtonItem and I have set it as self.navigationItem.leftBarButtonItem, such that when it is pressed, a UITableView begins editing and it turns into a "Done" button. When pressed again the view stops editing and the button returns to its normal state.
I would also like an "add" button to turn into a "Clear" button with a different action linked to it when the edit button is pressed.
(Much like in the iPhone "Phone" app's favourites tab, just that the plus button turns into a clear button when the Edit button is pressed).
I would really like to obtain the edit action and style etc in this way (self.editButtonItem), but I would also like to have an extra selector linked to the edit button.
How should I go about doing this? I have tried to create a category for UIBarButtonItem, but I don't really know what I should do with that.
Thanks.
To create a button whose title can change, you can do the following:
Define an ivar for the button:
UIBarButtonItem *_btnAddClear;
In viewDidLoad:
_btnAddClear = [[UIBarButtonItem alloc] initWithTitle:#"Add" style:UIBarButtonItemStyleBordered target:self action:#selector(addClearAction:)];
_btnAddClear.possibleTitles = [NSSet setWithObjects:#"Add", #"Clear", nil];
Since you want this button's title to change when the Edit/Done button is tapped, you can add code like the following:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
_btnAddClear.title = editing ? #"Clear" : #"All";
}
And lastly, the button handler:
- (void)addClearAction:(UIBarButtonItem *)button {
if (self.editing) {
// perform "clear" action
} else {
// perform "add" action
}
}
Give tag of UIBarButton such like 101;
and in BarButton Method write following
-(void)barButtonMethod
{
UIBarButtonItem * myButton = (UIBarButtonItem *) sender;
if(sender.tag == 101)
{
yourBtn.tag = 102;
// Write Your first action method such like
[self ActionMethod1];
}
else
{
yourBtn.tag = 101;
// Write Your second action method such like
[self ActionMethod2];
}
}
You don't really need a new action for the editButtonItem.
There is a property that tracks if the UIViewController is in editing state.
#property(nonatomic, getter=isEditing) BOOL editing
In order to do what you want, you can implement the following method in your UITableViewController:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated]
//Do your thing
}

UIbutton which displays a popover label briefly where the label would show halfway outside the button

How do I create a uibutton, which will show a uilabel of some text briefly something like a speech bubble that will appear and then disappear. The problem is the speech bubble will be a view lying halfway outside the button frame.
thanks for help on this.
Add a UIButton in the .xib file and give some name.
Add the folowing method in your code.
- (IBAction)bubbleButn:(UIButton *)btn
Then right click on the button and see the "Touch Up Inside" part in the menu. Then you can click and drag the right most circle to the files owner in the "Placeholders" section of the Xocde. Then you can see the method name comes in a menu. You can select our method from there.
Next we are going to implement our code.
At first you must declare a UILabel in the .h file.
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
UILabel *bubbleLabel_;
}
#end
and then in the .m file implement the button action and label settings.
- (IBAction)bubbleButn:(UIButton *)btn {
float half = btn.frame.size.width/2;
float yVal = btn.frame.size.height/2;
if(bubbleLabel_) {
/*
If you are using 'arc' no need of this statement
add this in the dealloc method also.
*/
[bubbleLabel_ release];
bubbleLabel_ = nil;
}
bubbleLabel_ = [[UILabel alloc] initWithFrame:CGRectMake(btn.frame.origin.x+half, btn.frame.origin.y+yVal, 40, 50)];
bubbleLabel_.text = #"Hi";
[self.view addSubview:bubbleLabel_];
[self performSelector:#selector(hideBubble) withObject:self afterDelay:3];
}
- (void) hideBubble {
[bubbleLabel_ removeFromSuperview];
}
The label named "Hi" will be there for 3 seconds.
Go on...

iOS - passing Sender (button) name to addSubview

I have a main view with 3 buttons. Clicking on any of the buttons adds a SubView.
The buttons have different titles and are all linked to IBAction "switchView"
The "switchView" code is below.
- (IBAction)switchView:(id)sender{
secondView *myViewController = [[secondView alloc] initWithNibName:#"secondView" bundle:nil];
[self.view addSubview:myViewController.view];
}
The "secondView" loads up correctly and everything works well.
The problem is I want to be able to know which button was the Sender.
I don't want to create 3 subviews, one for each button. The code and XIB would be absolutely the same>
The only difference would be a variable that I would like to set up in the second view (viewDidLoad method) depending on who is the Sender (which button was clicked)
Is this possible? Or I would need to create 3 subViews - one for each button?
Your help is greatly appreciated!
You can identify different buttons with the tag property.
e.g. with your method:
-(IBAction)switchView:(id)sender {
UIButton *button = (UIButton*)sender;
if (button.tag == 1) {
//TODO: Code here...
} else if (button.tag == 2) {
//TODO: Code here...
} else {
//TODO: Code here...
}
}
The tag property can be set via the InterfaceBuilder.
Hope this helps.
I think you can solve in 2 ways:
Create a property like:
#property (nonatomic, strong) IBOutlet UIButton *button1, *button2, *button3;
in your viewcontroller and link the buttons to them as referencing outlet on the XIB.
Give a different tag to each button on your xib and ask for the tag of the sender with UIButton *b=(UIButton*)sender; b.tag; like Markus posted in detail.
Solving my problem it all came down to transferring data between the mainView and subView.
In my mainView.h I declared an NSString and its #property
...
NSString *btnPressed;
}
#property(nonatomic, retain) NSString *btnPressed;
...
then in my mainView.m inside the switchView method I did this:
- (IBAction)switchView:(id)sender{
secondView *myViewController = [[secondView alloc] initWithNibName:#"secondView" bundle:nil];
btnPressed = [NSString stringWithFormat:#"%i", [sender tag]];
[myViewController setBtnPressed:self.btnPressed];
[self.view addSubview:myViewController.view];
}
This line in the code above actually takes care of transferring the data to the newly created subView:
[myViewController setBtnPressed:self.btnPressed];
Then in my secondView.h I declare exactly the same NSString *btnPressed and its #property (though this a completely different object than the one declared in main)
Then in my secondView.m I get the value of the button pressed I'm interested in.
- (void)viewDidLoad {
[super viewDidLoad];
int theValueOfTheButtonPressed = [self.btnPressed intValue];
}
This works well.
Don't forget to #synthesize btnPressed; as well as [btnPressed release]; in both mainView.m and secondView.m

Resources