Cannot Alter Custom UIBarButton Item - ios

I am trying to add a custom bar button to my project and I'm having a few problems. First lets go over the requirement for my button, it needs:
- to display a custom font
- to be enabled/disabled
- to have its colour animated based to provide user feedback.
So I first tried connecting a barButtonItem up through the storyboard and I could change the colour and enable disable it. However I could not change the font or add colour animation to it. I want to be able to use the following method which I am already using in the app to animate the colour:
- (void)textFlashTextfieldAnimation:(nonnull UITextField *)view duration:(NSTimeInterval)duration animateToColour:(UIColor*)animationColour textColor:(UIColor*)textColour completion:(void (^)(BOOL finished))completion {
[UIView transitionWithView:view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
view.textColor = animationColour;
} completion:^(BOOL finished) {
[UIView transitionWithView:view duration:2.0f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
view.textColor = textColour;
} completion:completion];
}];
}
Ideally I would be able to change this function to accept a barButtonItem / UIButton so that I could animate it easily. However if I connect the button up through storyboards I cannot access the button's layer so the animation is not possible.
I had started to go about this through code but I've gone down 2 dead ends. Here is a really basic implementation of a barButtonItem:
UIBarButtonItem *myButton=[[UIBarButtonItem alloc] initWithTitle:#"My Custom Button" style:UIBarButtonItemStylePlain target:self action:#selector(/*do something*/)];
[self.navigationItem setRightBarButtonItem:myButton];
Now this will work in the fact that I can use it like a storyboard button however I cannot alter the font or access the button's layer so it is also no good.
I then tried creating a fully custom view for my bar button by creating a UIView and a UIButton and then adding them to a barButtonItem, this can be seen here:
UIFont *barButtonFonts = [UIFont fontWithName:kFont size:16];
//Right Button
//create view
UIView *rightButtonView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 45, 25)];
//create button
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeSystem];
rightButton.backgroundColor = [UIColor clearColor];
rightButton.frame = rightButtonView.frame; //set frame = to view
[rightButton setTitle:NSLocalizedString(#"Save", nil) forState:UIControlStateNormal];
rightButton.titleLabel.font = barButtonFonts;
rightButton.tintColor = [UIColor redColor];
[rightButton addTarget:self action:#selector(actionMethod) forControlEvents:UIControlEventTouchUpInside];
[rightButtonView addSubview:rightButton];
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithCustomView:rightButtonView];
self.navigationItem.rightBarButtonItem = rightBarButton;
Now I have a barButtonItem that will display a custom font however it is has no UI interaction at all. It looks the same when enabled/disabled and when not-highlighted/highlighted. The button works as it should it just doesn't look like it should.
Should I create an outlet to this button somewhere in my code so that I can alter the button when in the view? Is it even possible to alter a button after it has been added to the navigation bar?
If anybody has any suggestions it would be appreciated!

Yeah barbuttonitem isn't modifieable after you added it to the bar. only way i can think is to remove the button and add a new one (with the new characteristics) when user interact with it. I suggest you to use a custom toolbar (like a normal UIView), then add a normal button to it. it would be easier to customize

Related

How can I set two buttons on the right side of an UINavigationBar?

I have made a standard Master-Detail application (with the Xcode template). I modified it, and now when I click one cell of the first table view the app shows another table view (which is the detail because is filtered by the clicked cell value).
In a standard table view I would have this situation on the UINavigationBar:
Edit Table title + (for adding new items)
I need the default back button of UINavigationBar too. Is it possible and allowed to do this? Graphically it would be like this:
< Back Table title Edit +
Do you know any other layout to display 3 button (back - edit - add) plus title all in the top bar?
Sorry for not posting images, Thanks in advance.
P.S. I'd like to know if it is possible to do the things I'm asking with built-in back button and edit button (I mean those that the system puts automatically to the navigation bar).
you need to setup array of right bar items to set up bar buttons right side...
Here is the code of 2 custom button to setup bar button items right side...you can use default button instead of this
UIButton *btnabout = [UIButton buttonWithType:UIButtonTypeCustom];
btnabout.frame = CGRectMake(0,8,30,30);
[btnabout setBackgroundImage:[UIImage imageNamed:#"about.png"] forState:UIControlStateNormal];
[btnabout addTarget:self action:#selector(callselector) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *about = [[UIBarButtonItem alloc] initWithCustomView:btnabout];
about.tintColor = [UIColor whiteColor];
UIButton *btnsetting = [UIButton buttonWithType:UIButtonTypeCustom];
btnsetting.frame = CGRectMake(0,8,30,30);
[btnsetting setBackgroundImage:[UIImage imageNamed:#"setting"] forState:UIControlStateNormal];
[btnsetting addTarget:self action:#selector(SettingData) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *setting = [[UIBarButtonItem alloc] initWithCustomView:btnsetting];
setting.tintColor = [UIColor whiteColor];
self.navigationItem.rightBarButtonItems =[NSArray arrayWithObjects:setting, about, nil];
// --- or if you want left side ----
// self.navigationItem.leftBarButtonItems =[NSArray arrayWithObjects:setting, about, nil];
[self.navigationItem setRightBarButtonItems:#[/*array of UIBarButtonItem*/] animated:NO]
Apple doc
to someone stuck with this problem in swift, here is the correct answer :
let barButton_array: [UIBarButtonItem] = [Button1, Button2]
navigationItem.setRightBarButtonItems(barButton_array, animated: false)

Fade UIBarButtonItem When Swapped

When I change my UIBarButtonItems they change abruptly, unlike the default which gives a nice but speedy fade animation. You can see this when segueing between view controllers, for instance, the back button will fade in and out. How can I simulate the same effect?
Update - Based on this answer - https://stackoverflow.com/a/10939684/2649021
It looks like you would have to do something like this to make the button itself fade out.
[self.navigationItem setRightBarButtonItem:nil animated:YES];
And do something like this to make it fade in
[self.navigationItem setRightBarButtonItem:myButton animated:YES];
Otherwise if you want more control over animation properties you would have to create a custom view I believe.
EDIT: I just confirmed that you can fade a UIBarButtonItem custom view using this.
As a test I created a simple project and dropped a UIBarButtonItem onto the navigation bar. I created an outlet to the view controller. In viewDidLoad on the view controller I setup a custom view
-(void)viewDidLoad{
[super viewDidLoad];
UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(0,0,40,40)];
lbl.text = #"test";
UIView *customView = [[UIView alloc]initWithFrame:CGRectMake(0,0,40,40)];
[customView addSubview:lbl];
self.barButtonItem.customView = customView;
}
As a test in viewDidAppear I animated it
-(void)viewDidAppear:(BOOL)animated
{
[UIView animateWithDuration:3.0
delay:3.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.barButtonItem.customView.alpha = 0;
}
completion:^(BOOL finished) {
NSLog(#"animation complete");
}];
EDIT: Here's a link to Apples Documentation for a full explanation of UIView animations.
https://developer.apple.com/library/ios/documentation/windowsviews/conceptual/viewpg_iphoneos/animatingviews/animatingviews.html
You might have to create a custom bar button item using a view or an image, and then animate the properties of the view as digitalHound shows.

Tab bar items to have different width

I am creating an iPhone app where i need to show 5 tab bar items . My requirement is I want first tab bar item to have smaller width than other 4 . is it possible and how to go about doing this. Please suggest .
I don't think it's possible to do this. UITabBar and UITabBarItem are two of the least customizable classes in UIKit. UITabBarItem does not even inherit from UIView.
I needed to something similar and ended up rolling my own TabBarController, TabBar and TabBarItem classes. If you only need the basic tab bar functionality it's not too much work. If you want the fancy new iOS 7 transitions it will be a lot more work.
Please check it out custom tab bar: https://github.com/aalittle/ALCustomTabBarController
In this sample, please go to TabBarView.xib file, you can change all the tabs buttons width and height according to your requirement.
Hope, It will may helpful,
:)
Create a subclass from UITabBarController and write this code in viewDidLoad.
-(void)viewDidLoad
{
[super viewDidLoad];
[self addCustomElements];
}
-(void)addCustomElements
{
// Backgroun
UIImageView* bgView = Your backgroun image for tab bar;
bgView.frame = CGRectMake(0, self.view.frame.size.height-50, 320, 50);
[self.view addSubview:bgView];
// Initialise our two images
UIImage *btnImage = default image for your tab item;
UIImage *btnImageSelected = selected image for your tab item;
tab1 = [UIButton buttonWithType:UIButtonTypeCustom]; //Setup the button
tab1.frame = // Set the frame (size and position) of the button)
[tab1 setImage:btnImage forState:UIControlStateNormal];
[btnMore setBackgroundImage:btnImageSelected forState:UIControlStateSelected];
[tab1 setTitle:#"title for 1st button" forState:UIControlStateNormal];
[tab1 setTag:0];
// Add my new buttons to the view
[self.view addSubview:tab1];
//repeat same for remaining button
// Setup event handlers so that the buttonClicked method will respond to the touch up inside event.
[tab1 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
set this subclass to your tab bar controller.

using transitionFromView with UIBarButtonItem customView

I'm trying to flip the UIBarButtonItem in a navigation bar like Apple does in the iPod app to switch between track listings and album art.
I've dragged a button onto my navigation bar in interface builder which as I understand inserts a UIBarButtonItem with the button as its customView.
I'm using the following method to flip the button's customView but it ends up flipping the entire navigation bar!
I was hoping it was a weird emulator glitch but it's also happening on device.
Has anyone encountered this or see where I might be going wrong?
[UIView transitionFromView:self.mapToggleBarButton.customView
toView:self.mapToggleBarButton.customView
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) {
}];
Turns out that this is exactly the expected behavior for UIView.transitionFromView and UIView.transitionWithView ...
The animation is applied to the superview of the object that you're swapping between. You don't have to have a reference to it or anything - just a plain UIView to enclose the button and the flip should work as expected!
I've written a little about it here: http://mathewsanders.com/animations-in-swift-part-two/
In your code, the fromView seems the same as the toView and that's why no animation. For example:
UIBarButtonItem *refresh = self.navigationItem.rightBarButtonItem;
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"On.png"]];
[UIView transitionFromView:((UIButton*)refresh.customView).imageView toView:imgView duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) {
//
UIButton *btn = ((UIButton*)refresh.customView);
[btn setImage:[UIImage imageNamed:#"On.png"] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(tap:) forControlEvents:UIControlEventTouchUpInside];
}];
Remember after flip animation, you should reset the UIButton, such as image, action and so on.

UIButtonBarItem looks wrong

I think this is going to be a stupid question, but I can't seem to find the answer. I have a few simple lines of code to put a button in the navigation bar:
UIBarButtonItem *cancelButton=[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"button-cancel.png"] style:UIBarButtonItemStylePlain target:self action:#selector(cancelPressed:)];
UINavigationItem *item = [[UINavigationItem alloc] init];
item.leftBarButtonItem = cancelButton;
item.hidesBackButton = YES;
[self.navigationBar pushNavigationItem:item animated:NO];
This button works fine, but it looks like this:
Any thoughts?
You probably want to create the bar button item using a custom view, where the custom view is a UIButton:
UIImage *cancelImage = [UIImage imageNamed:#"button-cancel"];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
cancelButton.frame = (CGRect){CGPointZero, cancelImage.size);
[cancelButton setImage:cancelImage forState:UIControlStateNormal];
UIBarButtonItem *cancelBarButton = [[UIBarButtonItem alloc] initWithCustomView:cancelButton];
Set your button (cancelButton) size according to the size of the button-cancel.png.
stopButton.frame = CGRectMake ();
Instead, create a custom type UIButton with your image. Set the target and selector of the UIbutton to what you wish the bar button item to do. Then initialize the bar button item as follows:
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
Where button is your UIButton using the desired image.
UIBarButtonItem/initWithImage: is typically used for making iconic buttons - not buttons that have text in them.
If you just want to change how the common textual UIBarButtonItem looks, you just need to set the background image of your bar button item. This way you don't have to have images for each button that contain your button text.
Docs: - (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
You can also set this app-wide by calling setBackgroundImage: on the UIBarButtonItem appearance proxy.
Lastly, note that you'll likely need to create a resizeable image to pass to setBackgroundImage. This will let your single image accomodate any button size. See UIImage/resizeableImageWithCapInsets:resizingMode: (iOS6) or UIImage/stretchableImageWithLeftCapWidth:topCapHeight: (pre iOS6)
You can certainly do what #Wain suggests but there are drawbacks. For one, your press-handler will no longer be sending a UIBarButtonItem as the 'sender'. That may not seem like much until you have a common handler that suddenly needs to determine if the sender is a UIBarButtonItem or a UIButton, or if you want to present a UIPopoverController against this BarButtonItem (but you only have the UIButton reference...)

Resources