MFMailCompose Custom buttons - ios

UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithCustomView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cancel.png"]]];
button.target = picker.navigationBar.topItem.leftBarButtonItem ;
button.action = picker.navigationBar.topItem.leftBarButtonItem.action;
picker.navigationBar.topItem.leftBarButtonItem=button;
Hi folks, I'm trying to change the style of the buttons of the mail composer. The above code does change the look of the button, however the action seems to be lost. Any ideas how I can overcome this? Thanks.

The fix for this is fairly simple. You add a method to this button and then define what should happen in the method. So first, put this line after you declare your button.
[button addTarget:self action:#selector(aButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
That will add a method to be called when the button is clicked/touched. Then, later in the code, you create the actual method that the button will be calling.
-(void)aButtonClicked:(id)sendr{
//Do stuff here
}
Hope this helped :)

Related

Set action for custom UIBarButtonItem

I've created a UIView that has to be added to BarButtonItem. I can't set action to this button though. Here's the code I am using:
self.menuBarButton = [[UIBarButtonItem alloc] initWithCustomView:self.containerView];
[self.menuBarButton setTarget:self];
[self.menuBarButton setAction:#selector(menuButtonTapped)];
self.navigationItem.leftBarButtonItem = self.menuBarButton;
The action doesn't run with success. I also tried to set an action directly to bar button after it's set to custom.
[self.navigationItem.leftBarButtonItem setTarget:self];
[self.navigationItem.leftBarButtonItem setAction:#selector(menuButtonTapped)];
When I do it for the usual barbutton item it works. Could you help spotting what's wrong?
A UIBarButtonItem initialized with a custom view expects the view to handle user interaction:
The bar button item created by this method does not call the action method of its target in response to user interactions. Instead, the bar button item expects the specified custom view to handle any user interactions and provide an appropriate response.
If your UIView doesn't handle any user interaction yet, then as Miken says, you can replace the UIView with a UIButton that you've configured with addTarget:selector.
In particular, if you're trying to set an image, UIButton can do that via setImage:forState:.
See also this answer.
When you use a custom view for a UIBarButtonItem, then you have to handle the actions yourself. Replace your custom view with a UIButton, or add a UIButton to your custom view, and then add a target & selector to the button.
Here's an example but keep in mind I'm free-forming this example, so it may not be 100% accurate code but the concept will be the same.
UIButton *button = [UIButton buttonWithType:UIBarButtonTypeCustom];
UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithCustomView:button];
[button addTarget:self selector:#selector(myBtnClk)];
To add action to a button you need two things: create a method, then add it to the button. Here is the method (pay attention to the syntax) :
- (IBAction) my_method : (id) sender {
UIButton * btn = sender;
}
Now the action assignment (where the button was created) :
[ my_button addTarget : self
action : #selector( my_method : )
forControlEvents : UIControlEventTouchUpInside ];
Instead of using - setAction alone, I recommend using: - addTarget:action:forControlEvents:. In iOS (AppKit) there are many type of events. You can take a look at the attached image for reference. Typically Touch up inside is appropriate for button press down.
I decided this problem. All answers was about adding target and action to UIButton and then create a UIBarButtonItem with this button. But as I said it's really necessary to set UIView to this button(I've forgotten to say it's necessary because this UIView has animation, maybe that's why all answers was good but wrong for my situation.)
But one answer(https://stackoverflow.com/a/28054357/4464891) from Jason Owen gives me great idea. I have to use my custom view, so I've set selector to my custom UIView by adding UITapGestureRecognizer with initWithTarget:action::
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(menuButtonTapped)];
[self.containerView addGestureRecognizer:tapRecognizer];
And when I click button tapRecognizer runs my selector. So that's it. Hope it'll be helpful for someone=)

Intercept back navigation in iOS7

I want to stop somebody going back on my Navigation Controller if they haven't saved their changes. Most posts on SO discuss overriding the back button (with a variety of techniques to do this). However, iOS7 allows you to now swipe to go back in a navigationViewController...
I did see the UINavigationControllerDelegate which looks like the right type of delegate I'd want to implement but I see no way to cancel a navigation action. Any ideas how to do this?
Unfortunately nothing changed in iOS7, you still need to fake your back button if you want to put some check into it.
By the way it easier now since you don't need to fake the arrow button.
Edit:
to do that:
UIButton *backButton = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 44.0f, 30.0f)];
[backButton setImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(popVC) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];

Adding action and target to a custom Navigation BarButtonItem?

I am trying to customize the Navigation Bar by adding a custom button to the rightBarButtonItem. Creating one is pretty straight forward.
UIImage *myImage = [UIImage imageNamed:#"menu-icon.png"];
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setFrame:CGRectMake(0, 0, myImage.size.width, myImage.size.height)];
[myButton setBackgroundImage:myImage forState:UIControlStateNormal];
UIBarButtonItem *myButtonItem = [[UIBarButtonItem alloc] initWithCustomView:myButton];
[navItem setLeftBarButtonItem:myButtonItem animated:YES];
Looks good, except that now I can't set the target or action properties. The following code does nothing:
myButtonItem.target = myTarget;
myButtonItem.action = #selector(myButtonAction);
I found that the reason it's not working is because I initialized the UIBarButtonItem with -initWithCustomView. Apples documentation says:
The bar button item created by this method does not call the action method of its target in response to user interactions. Instead, the bar button item expects the specified custom view to handle any user interactions and provide an appropriate response.
I'm a little confused by what exactly apple means by that. Am I supposed to create a custom control or something? I haven't really done that yet and I'm not sure where to start.
Does anyone have any suggestions on how to do this or an alternative way to set up a custom Navigation Bar Button?
ANSWERED----------------------------------------------------------
Just had to add this method to the UIButton:
[myButton addTarget:myTarget action:#selector(myButtonAction) forControlEvents:UIControlEventTouchUpInside];
It's pretty straight forward, you need to add target for uibutton not for uibarbuttonitem.
To explain more what you want for uibarbuttonitem is respond touch up inside action method, as documentation says that you need to do that for uibutton as you are initializing your uibarbuttonitem with custom view in your case uibutton.
Add an action and target to a UIButton like this:
[myButton addTarget:self
action:#selector(handleMyButtonTap)
forControlEvents:UIControlEventTouchUpInside];
Add an action and target to a UIBarButtonItem like this:
[myBarButtonItem setAction:#selector(handleBarButtonTap)];
[myBarButtonItem setTarget:aTarget];
With the help of answers by hgwhittle and Mustafa I implemented and it works perfect
here is the complete snip may help someone
//Create ImageButton
UIImage *shareBtnIcon = [UIImage imageNamed:#"dummy_share_icon_22"];
UIButton *shareButton = [UIButton buttonWithType:UIButtonTypeCustom];
[shareButton setFrame:CGRectMake(0, 0, shareBtnIcon.size.width, shareBtnIcon.size.height)];
[shareButton setBackgroundImage:shareBtnIcon forState:UIControlStateNormal];
[shareButton addTarget:self action:#selector(shareButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
//Create BarButton using ImageButton
UIBarButtonItem *shareBarBtn = [[UIBarButtonItem alloc] initWithCustomView:shareButton];
//Add BarButton to NavigationBar
self.navigationItem.rightBarButtonItems = [[NSArray alloc] initWithObjects:shareBarBtn, nil];
//method for share butto click
-(void) shareButtonClicked:(UIButton*)sender
{
NSLog(#"you clicked on share button %ld");
}

Issue With My Custom Navigation Bar Back Button Xcode

I'm working in Xcode 4.3.2 using storyboards. I've created a segue between two views by clicking on the button I want to create a segue and control+click+drag a connection to the next view controller. Of course this creates an automatic/default back button in the navigation bar in the next view controller. What I want to do is customize the look of this back button. SO, I looked around online and found this code:
self.navigationItem.hidesBackButton = YES;
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 4, 40, 40)];
[button setImage:[UIImage imageNamed:#"homeButton.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(backAction) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = back;
It works great to change the LOOK of the button, but the problem now is that when I click that button, Xcode throws an error: "unrecognized error sent to instance..."
Can anyone help me to figure out how to now add the proper functionality to my custom back button? Thanks.
Have you implemented the method - (void)backAction?
To make the back button behave as such with a navigation controller, A possible implementation could look like:
- (void)backAction {
[self.navigationController popViewControllerAnimated:YES];
}
This may need to be tweaked depending on your app setup and what you want it to do when the button is pressed but it should be a good starting point

Custom Button initWithImage displaying a default button behind the custom image

I am trying to make a button for my navigation bar with a custom image. When I run the following code, the button appears as it should, except you can see another wider button behind it, sticking out the sides. How do I get rid of that other button?
UIBarButtonItem *emailButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"emailBut"]
style:UIBarButtonSystemItemCompose
target:self
action:#selector(emailSheet)];
self.navigationItem.rightBarButtonItem = emailButton;
Hmm... UIBarButtonSystemItemCompose is a system icon, so I guess you are probably overlaying your icon on top of it. You should instead use UIBarButtonItemStylePlain (or other styles) for your style: argument.
Edit:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(...)];
[button setBackgroundImage:someImage];
[button addTarget:self action:#selector(something:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
[self.navigationItem setRightBarButtonItem:barButtonItem];
Ok, for some reason initWithImage only puts the image in the center of a default button. The fix was to initWithCustomView as iBlue suggested.
Another thing to note is that the barBackButton doesn't allow custom views, so I had to make that one a leftButton instead of a backButton, with my own go back method. I hope Apple makes this easier in the future.

Resources