我不使用导航控制器,我正在使用故事板。
我必须从1个视图控制器转换到其他视图,我正在使用segue。
现在我将segue样式设置为Custom,并在相应的类中重写perform
方法。
-(void)perform
{
UIViewController *sourceViewController = [self sourceViewController];
UIViewController *destinationViewController = [self destinationViewController];
CATransition *transition = [CATransition animation];
transition.duration = 0.25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[sourceViewController.view.layer addAnimation:transition forKey:kCATransition];animated:NO];
[sourceViewController presentViewController:destinationViewController animated:YES completion:nil];
}
但目标视图控制器modalTransitionStyle
还有一个属性。
所以现在,源VC从左向右移动,好像它被推送一样,但我想表明它正被目标视图控制器推送。相反,目标VC在默认情况下执行“覆盖垂直”,modalTransitionStyle
属性只有四个选项可用,但没有一个适用于我。
我认为要使它工作,这个动画应该被添加到一些超级视图层,一个超级视图,从中可以看到两个视图控制器。但是没有这样的超级视图..
答案 0 :(得分:7)
通常你会给storyController提供一个storyboardId,并从sourceViewController中调用它:
//push next view
UIStoryboard *storyboard = self.storyboard;
YourViewControllerClass *destVC = [storyboard instantiateViewControllerWithIdentifier:@"StoryboardID"];
[self.navigationController pushViewController:destVC animated:YES];
您可以选择手动执行此操作:
// Get the views.
UIView * fromView = sourceViewController.view;
UIView * toView = destinationViewController.view;
// Get the size of the view area.
CGRect viewSize = fromView.frame;
// Add the toView to the fromView
[fromView.superview addSubview:toView];
// Position it off screen.
toView.frame = CGRectMake( 320 , viewSize.origin.y, 320, viewSize.size.height);
[UIView animateWithDuration:0.4 animations:
^{
// Animate the views on and off the screen. This will appear to slide.
fromView.frame =CGRectMake( -320 , viewSize.origin.y, 320, viewSize.size.height);
toView.frame =CGRectMake(0, viewSize.origin.y, 320, viewSize.size.height);
}
completion:^(BOOL finished)
{
if (finished)
{
// Remove the old view from its parent.
[fromView removeFromSuperview];
//I use it to have navigationnBar and TabBar at the same time
//self.tabBarController.selectedIndex = indexPath.row+1;
}
}];
** 编辑 **
反函数(类似于导航控制器中的后退按钮):
// Get the views.
UIView * fromView = fromViewController.view;
UIView * toView = destViewController.view;
// Get the size of the view area.
CGRect viewSize = fromView.frame;
// Add the to view to the tab bar view.
[fromView.superview addSubview:toView];
// Position it off screen.
toView.frame = CGRectMake( -320 , viewSize.origin.y, 320, viewSize.size.height);
[UIView animateWithDuration:0.4 animations:
^{
// Animate the views on and off the screen. This will appear to slide.
fromView.frame =CGRectMake( 320 , viewSize.origin.y, 320, viewSize.size.height);
toView.frame =CGRectMake(0, viewSize.origin.y, 320, viewSize.size.height);
}
completion:^(BOOL finished)
{
if (finished)
{
// Remove the old view from the tabbar view.
[fromView removeFromSuperview];
}
}];
答案 1 :(得分:1)
我的应用中的所有ViewControllers都继承自MyViewController
,除了其他一些默认行为外,还有此属性:
@property(readwrite, nonatomic) BOOL slideFromSide;
这段代码:
- (void) presentViewController: (UIViewController*) vc animated: (BOOL) flag completion: (void (^)(void)) completion
{
BOOL slideIn = NO;
if ([vc isKindOfClass: [MyViewController class]])
{
MyViewController *svc = (MyViewController*) vc;
slideIn = svc.slideFromSide;
}
if (slideIn)
{
[self addChildViewController: vc];
[self.view addSubview: vc.view];
CGRect frame = vc.view.frame;
frame.origin.x = frame.size.width;
vc.view.frame = frame;
frame.origin.x = 0;
[UIView animateWithDuration: 0.33
animations: ^{
vc.view.frame = frame;
}
];
}
else
{
[super presentViewController: vc animated: flag completion: completion];
}
}
- (IBAction) backAction: (id) sender
{
if (_slideFromSide)
{
CGRect frame = self.view.frame;
frame.origin.x = frame.size.width;
[UIView animateWithDuration: 0.33
animations: ^{
self.view.frame = frame;
}
completion:^(BOOL finished) {
[self removeFromParentViewController];
}
];
}
else
{
[self dismissViewControllerAnimated: YES completion: nil];
}
}
然后,在我想要滑入的ViewControllers中,我有:
- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName: nibNameOrNil bundle: nibBundleOrNil];
if (self)
{
self.slideFromSide = YES;
// Whatever else you want to do
}
return self;
}
调用新的ViewController就像正常一样:
WhateverViewController *vc = [WhateverViewController alloc] initWithNibName: nil bundle: nil];
[self presentViewController: vc animated: YES completion: nil];