我有一个带有许多图像按钮的“主屏幕”。在点击其中一个按钮后,细节视图控制器被推到导航控制器上。但是,在视觉上,我希望按钮中的图像保持在屏幕上的同一位置,同时新的视图控制器转换到它后面的位置。
模态控制器的一个示例是将照片添加到电子邮件或消息中。您在图库中选择的照片会变大(就像它向您移动一样),而撰写邮件视图会在背景中滑动到位,然后照片会缩小到消息视图的位置。
我想到了几个选项:
点击按钮后,将图像放在屏幕上的同一位置,作为UIWindow的子视图。执行动画/过渡,然后将图像作为新viewcontroller视图的子视图。
与上述相同,但模态视图控制器具有清晰的背景
让UINavigationController成为子视图并使用UINavigationController的父视图执行上述操作
上面的所有选项都是类似的,但我很好奇是否有更好的方法来做到这一点,代码将存在于何处。我应该将UINavigationController子类化并将转换代码放在那里吗?或者也许AppDelegate(虽然看起来不对)?
答案 0 :(得分:2)
我会在导航控制器或窗口中添加子视图,但是需要一些视图层次结构体操。
您需要为master
和detail
视图控制器提供一种方法,以便对每个imageView
上的ivar进行引用。
// PSMasterViewController.m
@interface PSMasterViewController ()
@property (nonatomic, strong) UIImageView *imageView;
@end
@implementation PSMasterViewController
@synthesize imageView = _imageView;
// ...
@end
我把它放在实现中,因为我不关心它是否为主视图控制器公开,但你的需求可能不同。
detailViewController
// PSDetailViewController.h
@interface PSMasterViewController : UIViewController
@property (nonatomic, strong) UIImageView *imageView;
@end
// PSDetailViewController.m
@implementation PSDetailViewController
@synthesize imageView = _imageView;
// ...
@end
现在假设已经在主视图控制器中创建并显示了imageView,我们需要在我们即将推出时实现一些视图体操
- (void)methodThatPushesTheNextViewController;
{
CGRect destinationFrame = [self.view convertRect:self.imageView.frame toView:self.navigationController.view];
[self.imageView removeFromSuperview];
[self.navigationController.view addSubview:self.imageView];
self.imageView.frame = destinationFrame;
PSDetailViewController *detailViewController = [[PSDetailViewController alloc] init];
detailViewController.imageView = self.imageView;
self.imageView = nil; // The detailViewController should own this now
[self.navigationController pushViewController:detailViewController animated:YES];
}
现在在详细视图控制器中,我们需要做的与我们刚刚做的相反,viewDidAppear:
是一个好地方,尤其是你提到的你可能想要移动和扩展
- (void)viewDidAppear:(BOOL)animated;
{
[super viewDidAppear:animated];
CGRect startFrame = [self.view convertRect:self.imageView.frame fromView:self.navigationController.view];
[self.imageView removeFromSuperview];
[self.view addSubview:self.imageView];
self.imageView.frame = startFrame;
[UIView animateWithDuration:0.25f
animations:^{
self.imageView.frame = [self someNewFrame];
}];
}
答案 1 :(得分:0)
选项1
你也可以在没有ModalViewController的情况下做到这一点。首先要记住的是,您必须删除图像并再次移动到pushViewController,因为如果发生视图转换,则会再次添加新的viewController,并且您之前的视图将消失。 所以这样做是通过向被推送的viewController发送NSNotification并使用相同的框架创建视图。还要记得在推送新的ViewController之前从superview中删除视图。
<强>选项2 强>
如果需要拥有相关视图的所有视图控制器都是从单个ViewController子类继承的,则可以调用[super init]方法创建视图并将其添加到viewDidLoad方法中。
答案 2 :(得分:-1)
您可以根据自己的想法在视图上执行“UIView动画”,也可以使用iCarousel进行更清晰的动画icarousel SourceCode