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.
Related
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.
Do any of you know how I could possibly add an animation that is triggered when a UIButton is pressed, and the UIButton turns aand enlarges at the same time, and on the other side I can show another view? A bit like in dashboard on a Mac, with the info button on the widgets...
You can use transitions:
[UIView transitionWithView:containerView duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
buttonView.hidden = YES;
otherView1.hidden = NO;
otherView2.hidden = NO;
otherViewEtc.hidden = NO;
} completion:nil];
You would then have a containerView which contains the flip button and the alternate view hidden, and in the transition, you can hide the first view and show the alternate view...
I have a case where I need to open a new UIViewController on IBAction. This new UIViewController is supposed to be transparent. When I do a normal modal transition it hides the old UIViewController. Any suggestions on this?
For your purposes you will want to tell your modal View Controllers view property to change alpha. (best done in the view controllers viewDidLoad)
It's as simple as:
- (void) viewDidLoad
{
[self.view setAlpha:0.5];
}
Now, the other approach would be to just use a new UIView added as a subview of your main view controller. The following will show your how to animate it in.
UIView *myNewView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[myNewView setAlpha:0.0];
[self.view addSubview:myNewView];
[UIView animateWithDuration:1.5 animations:^{
[myNewView setAlpha:0.5];
}];
EDIT: To change the alpha of the background view and preserve the alpha of its subviews, try setting it up like this.
[myNewView setBackgroundColor:[[UIColor blueColor] colorWithAlphaComponent:0.2]];
[myNewViewsSubView setBackgroundColor:[[UIColor redColor] colorWithAlphaComponent:1.0]];
How can I develop a toolbar like this one, with a button that when it's pressed reveals another toolbar (sliding on top of the current one)? This is a screenshot from the iPhoto application from Apple.
http://i.stack.imgur.com/dKYZq.png
I got this to work using the following (Disclaimer: THIS MAY VIOLATE THE HIG!):
I added a new, basic UIViewController.
I added a UIToolbar to the view of the UIViewController. I connected this UIToolbar to a property in my UIViewController named "BaseToolbar".
To "BaseToolbar", I added a button. I connected this button to an IBAction called "AddPressed:" in my UIViewController.
I added a UIToolbar to the UIViewController's xib, BUT NOT ON THE UIViewController's view. I just added it onto the design surface. I connected this UIToolbar to a property in my UIViewController named "SecondToolbar".
To "SecondToolbar", I added a button. I connected this button to an IBAction called "TrashPressed:" in my UIViewController.
I used the following code:
- (IBAction)AddPressed:(id)sender {
CGRect secondCurrRect = [[self SecondToolbar] frame];
[[self SecondToolbar] setFrame:CGRectMake(0, -1 * secondCurrRect.size.height, secondCurrRect.size.width, secondCurrRect.size.height)];
[[self view] addSubview:[self SecondToolbar]];
[[self view] bringSubviewToFront:[self SecondToolbar]];
[UIView animateWithDuration:1.0
animations:^(void){
[[self SecondToolbar] setFrame:CGRectMake(0, 0, secondCurrRect.size.width, secondCurrRect.size.height)];
}];
}
- (IBAction)TrashPressed:(id)sender {
CGRect secondCurrRect = [[self SecondToolbar] frame];
[UIView animateWithDuration:1.0
animations:^(void){
[[self SecondToolbar] setFrame:CGRectMake(0, -1 * secondCurrRect.size.height, secondCurrRect.size.width, secondCurrRect.size.height)];
}
completion:^(BOOL finished) {
[[self SecondToolbar] removeFromSuperview];
}];
}
Using that code, the new UIToolbar slides on/off ON TOP OF the "base" UIToolbar.
Edit/Update
Let's try a different tactic.
(This assumes you're adding the UIToolbar objects to your xib at design time)
Add Toolbar #1 (the one that is always on-screen) to the top of the view and position it like you want.
Add Toolbar #2 (the one that slides on/of) underneath Toolbar #1 and build it out with the buttons you want.
Put the following line of code into your -(void)viewDidLoad method (this will move the second toolbar off-screen):
[[self Toolbar2] setFrame:
CGRectMake(0, // origin.x
-[[self Toolbar2] frame].size.height, // origin.y
[[self Toolbar2] frame].size.width, // size.width (remains the same)
[[self Toolbar2] frame].size.height) // size.height (remains the same)
];
Then, use the code from above, but skip the calls to addSubview: and removeFromSuperview.
Does that make sense now?
In fading a view controller in from black, I am doing the following within viewDidLoad:
Creating a UIView with a black background;
Giving the UIView an alpha value of 1.0f;
Adding the UIView as a subview of [self view];
Fading the black UIView out via animateWithDuration by changing its alpha value to 0.0f; and
Removing the black UIView from [[self view] subviews]
More often than not, this works as planned. Occasionally, however, I see a glimpse of the view controller I want initially hidden, just before the black UIView is drawn.
Is there a way to avoid this? Is there a better method to place this code in than viewDidLoad?
Many thanks
Yes, add the view in the loadView method and do the actual animation in viewDidLoad or viewDidAppear. Or do as the above commentor said and simply use the view alpha.
I would create the UIView that I want hidden in UIViewController's nib file, then link that to via an IBOutlet
#interface SomeViewController: UIViewController
{
IBOutlet UIView *blackView;
}
then in UIViewController's -(void) viewDidLoad; method, I would do the following
- (void)viewDidLoad
{
[super viewDidLoad];
// Fade the opacity of blackView over 1 second,
// then remove it from the view controller.
[UIView animateWithDuration:1
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
blackView.layer.opacity = 0;
}
completion:^(BOOL finished) {
// This line prevents the flash
blackView.layer.opacity = 0;
[blackView removeFromSuperview];
}];
}