我正在尝试在两个视图之间切换。这很容易,代码在下面,但我也想同时翻转用于执行翻转的按钮。
当您在播放曲目时,您可以在iPod应用程序中看到此行为;点击翻盖按钮可以在封面图片和曲目列表之间翻转,但它会同时翻转按钮。
这是导航控制器上的一个页面,我要翻转的按钮是rightBarButtonItem
。
这是我到目前为止的代码。这会翻转视图,但不会翻转右边的BarButton。
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: 0.5f];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
showingBackside = !showingBackside;
if (showingBackside) {
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft
forView: self.view
cache: YES];
[self.view addSubview: backside.view];
[frontside.view removeFromSuperview];
} else {
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight
forView: self.view
cache: YES];
[self.view addSubview: frontside.view];
[backside.view removeFromSuperview];
}
// flip image, too
NSString *newImage = showingBackside ? @"backside.png" : @"frontside.png";
[(self.navigationItem.rightBarButtonItem) setImage: [UIImage imageNamed: newImage]];
[UIView commitAnimations];
(此处的图像翻转代码可能无法编译;我在尝试解释我尝试做的事情之后添加了它。)
我遇到麻烦的地方是我想更改导航控制器中最右边的按钮,以便同时翻转。
我该怎么做?我的动画是什么视图,我是作为同一动画块的一部分还是作为单独的动画块执行的?任何提示都会受到赞赏,我绝对没有很好的处理动画。
答案 0 :(得分:5)
有一些讨论here,但解决方案并不那么优雅。
首先,由于UIBarButtonItem
不是UIView
的后代,因此您可能无法直接在UIBarButtonItem
上使用UIKit动画。但是,您可以尝试设置customView
并为其设置动画。您可以使用相同的动画块。
答案 1 :(得分:2)
好的,这就是我实际采取的措施:
我已经在使用自定义标题视图了。我没有使用rightBarButtonItem
,而是将自定义视图扩大了。
我创建了按钮两侧的图像,包含导航框,并将它们嵌入到应用程序中。在我的标题视图中,我说:
UIView
将替代正确的控件(称之为rightControl
),并且位置恰当。UIView
上的一个按钮,响应UIControlEventTouchUpInside
并触发flipSide:
。在运行时,我为每个州创建一个UIImageView
。我把UIImageView
放在rightControl
中,但隐藏了那个不是默认的那个。我在专用动画块中的flipSide:
中切换隐藏的标志。
非常奇怪。但它确实有效。
答案 2 :(得分:2)
只需使用自定义UIView作为右侧导航按钮,其中包含两个可在其间切换的按钮。
您可以使用直接方法创建显示为右侧导航按钮项的自定义UIView。这个UIView应该包含你想要翻转的两个UIButtons。请记住,UIButtons也是UIViews,所以可以使用相同的过渡来翻转它们,可以翻转普通的UI视图,当然也可以点击它们!以下是一些有效的示例代码:
注意:我使用便利功能创建按钮作为UIViewController的自定义类别(注意:您可以添加相同的代码来为UIView创建自定义类别,只需复制相同的行并用UIView替换UIViewController) - 如果你想要使用它只是通过在下面包含这个代码创建一个自定义类别,或者你可以像往常一样创建UIButtons。
// create custom category for UIViewController to allow common button creation routine, add to .m or .mm file or add to a .h file and #import that .h file
@interface UIViewController (ButtonAndSelector)
- (UIButton *)createUIButtonWithImage:(UIImage *)image forState:(UIControlState)state withSelector:(SEL)selector usingFrame:(CGRect)buttonImageFrame;
@end
@implementation UIViewController (ButtonAndSelector)
- (UIButton *)createUIButtonWithImage:(UIImage *)buttonImage forState:(UIControlState)state withSelector:(SEL)selector usingFrame:(CGRect)buttonImageFrame
{
UIButton *button = [[UIButton alloc] initWithFrame:buttonImageFrame];
[button setBackgroundImage:buttonImage forState:state];
[button addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
[button setShowsTouchWhenHighlighted:YES];
return button;
}
@end
// add this to your .h file:
@property (strong, nonatomic) UIView *coverListView;
@property (strong, nonatomic) UIButton *listButton;
@property (strong, nonatomic) UIButton *coverButton;
- (void)animateCoverListButtonFlip;
// add this to your .m or .mm file to synthesize the variables:
@synthesize coverListView;
@synthesize listButton;
@synthesize coverButton;
// add this to your .m or .mm file in the viewDidLoad:
// setup right button bar (flips between list icon and coverart image)
self.coverListView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 32, 30)];
self.coverListView.backgroundColor = [UIColor clearColor];
self.coverListView.opaque = NO;
self.listButton = [self createUIButtonWithImage:[UIImage imageNamed:@"navbar_icon_tracklisting"] forState:UIControlStateNormal withSelector:@selector(showHideQueue) usingFrame:CGRectMake(0, 0, 32, 30)];
self.listButton.backgroundColor = [UIColor clearColor];
self.listButton.showsTouchWhenHighlighted = NO;
self.coverButton = [self createUIButtonWithImage:[UIImage imageNamed:@"default_coverart_small"] forState:UIControlStateNormal withSelector:@selector(showHideQueue) usingFrame:CGRectMake(0, 0, 32, 30)];
[self.coverListView addSubview:self.coverButton]; // show coverButton by default
self.coverButton.showsTouchWhenHighlighted = NO;
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.coverListView];
[self.navigationItem setRightBarButtonItem:barButtonItem];
// add this to viewDidAppear if you want to flip the button when the screen appears like the build in iPod app does
[self animateCoverListButtonFlip];
// add this routine to flip the right navigation bar custom view / buttons
- (void)animateCoverListButtonFlip
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:([self.listButton superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) forView:self.coverListView cache:YES];
if ([self.listButton superview]) {
[self.listButton removeFromSuperview];
[self.coverListView addSubview:self.coverButton];
} else {
[self.coverButton removeFromSuperview];
[self.coverListView addSubview:self.listButton];
}
[UIView commitAnimations];
}
// when the playing album cover changes, remember to update the coverButton:
UIImage *artworkImage; // set this to the current playing album image
[self.coverButton setImage:artworkImage forState:UIControlStateNormal];
// don't forget to call the animateCoverListButtonFlip in the button click handler (shown above as showHideQueue) that shows and hides the cover/queue(list of album tracks0 - something like this:
- (void)showHideQueue
{
[self animateCoverListButtonFlip];
/* replace the code below that is commented out here with your own code that transitions between your cover view and your list view of album tracks, this code shows my transition and references views that are not part of this example/answer, but you don't need those - you'll have your own cover view (musicPlayerView) and list view (musicQueueView) to flip between.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:([musicQueueView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) forView:self.contentView cache:YES];
if ([musicQueueView superview]) { // if music queue is displayed
[musicQueueView removeFromSuperview];
[self.contentView addSubview:musicPlayerView];
} else {
[musicPlayerView removeFromSuperview];
[self.contentView addSubview:musicQueueView];
[[musicQueueView queueTableView] reloadData];
}
[UIView commitAnimations];*/
}