我有自定义转换,我将它应用于符合UIViewControllerTransitioningDelegate
协议的ViewController。我的过渡工作正常。但是,当我将UIViewControllerTransitioningDelegate
协议更改为UINavigationControllerDelegate
协议时,它的工作方式很奇怪。
The function i want to realize
Strange presentation with only one piece of toView
MyTransitioning:
#import "MyTransitioning.h"
#define PARTS_COUNT 4
@interface MyTransitioning()
@property (nonatomic) CGFloat partWidth;
@property (nonatomic) CGFloat partHeight;
@end
@implementation MyTransitioning
-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return 1.0;
}
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* fromCtrl = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController* toCtrl = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView* fromView = fromCtrl.view;
UIView* toView = toCtrl.view;
UIView* container = [transitionContext containerView];
CATransform3D transform = container.layer.transform;
transform.m34 = -0.01;
[container.layer setSublayerTransform:transform];
NSArray<UIView*>* fromViewParts = [self spliteView:fromView];
NSArray<UIView*>* toViewParts = [self spliteView:toView];
[self addViews:toViewParts ToContainer:container isFromView:NO];
[self addViews:fromViewParts ToContainer:container isFromView:YES];
[fromView removeFromSuperview];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^
{
[self strechViews:toViewParts];
[self compressViews:fromViewParts ToLeft:YES];
} completion:^(BOOL finished)
{
if (!finished)
{
NSLog(@"not finish");
}
[self removeViewsfromSuper:fromViewParts];
[self removeViewsfromSuper:toViewParts];
[container addSubview:toView];
[transitionContext completeTransition:!transitionContext.transitionWasCancelled];
}];
}
-(NSArray*)spliteView:(UIView*)view
{
self.partWidth = view.bounds.size.width / PARTS_COUNT;
self.partHeight = view.bounds.size.height;
CGRect region = CGRectMake(0, 0, self.partWidth, self.partHeight);
NSMutableArray<UIView*>* viewParts = [NSMutableArray array];
for (int i = 0; i < PARTS_COUNT; i++)
{
region.origin.x =self.partWidth * i;
UIView* partView = [view resizableSnapshotViewFromRect:region afterScreenUpdates:YES withCapInsets:UIEdgeInsetsZero];
[viewParts addObject:partView];
partView.frame = region;
}
return viewParts;
}
-(void)addViews:(NSArray<UIView*>*)views ToContainer:(UIView*)container isFromView:(BOOL)isFromView
{
isFromView ? [self strechViews:views] : [self compressViews:views ToLeft:NO];
for (UIView* view in views)
{
[container addSubview:view];
}
}
-(void)compressViews:(NSArray<UIView*>*)views ToLeft:(BOOL)toLeft
{
CGFloat x = toLeft ? 0 : self.partWidth * 4;
int isClockWise = -1;
CGPoint position = CGPointMake(x, self.partHeight / 2);
for (UIView* view in views) {
isClockWise *= -1;
view.layer.anchorPoint = CGPointMake(0.5 - isClockWise * 0.5, 0.5);
view.layer.position = position;
view.layer.transform = CATransform3DMakeRotation(M_PI_2 * isClockWise, 0, 1, 0);
}
}
-(void)strechViews:(NSArray<UIView*>*)views
{
int isClockWise = -1;
for (UIView* view in views)
{
isClockWise *= -1;
view.layer.anchorPoint = CGPointMake(0.5 - isClockWise * 0.5, 0.5);
NSLog(@"%@",NSStringFromCGPoint(view.layer.anchorPoint));
CGPoint position = view.layer.position;
position.x = self.partWidth * [views indexOfObject:view] + (isClockWise == 1 ? 0 : self.partWidth);
view.layer.position = position;
view.layer.transform = CATransform3DIdentity;
NSLog(@"%@",NSStringFromCGRect(view.frame));
}
}
-(void)removeViewsfromSuper:(NSArray<UIView*>*)views
{
for (UIView* view in views)
{
[view removeFromSuperview];
}
}
@end
的ViewController:
#import "ViewController.h"
#import "MyTransitioning.h"
#import "SecondController.h"
@interface ViewController ()<UINavigationControllerDelegate>
//@interface ViewController ()<UIViewControllerTransitioningDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//-(id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
//{
// return [MyTransitioning new];
//}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
self.navigationController.delegate = self;
// SecondController* ctrl = [segue destinationViewController];
// ctrl.transitioningDelegate = self;
}
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
if (operation == UINavigationControllerOperationPush) {
return [MyTransitioning new];
}
return nil;
}
@end
答案 0 :(得分:0)
如果您的问题在PresentViewController
和Push
之间存在差异,那么pop
查看控制器,
PushViewController
推送视图控制器是导航控制器的属性。当你想从一个控制器向前移动时,你可以使用它。PopViewController
Pop视图控制器也是导航控制器的属性。如果你想在导航堆栈中向后移动,你可以这样做。 PresentViewController
/模型视图控制器
当前视图控制器不是导航控制器的属性。要执行push/pop
,您的控制器应直接或间接地使用UINavigationController
进行子类化。然而,要呈现视图控制器,您不需要引用导航控制器,直接调用[self presentViewController..]