Ios 将TLLayoutTransitioning与ViewController一起使用。使用LayoutOuttoLayoutNavigationTransitions

Ios 将TLLayoutTransitioning与ViewController一起使用。使用LayoutOuttoLayoutNavigationTransitions,ios,objective-c,uicollectionview,uicollectionviewlayout,Ios,Objective C,Uicollectionview,Uicollectionviewlayout,我正在尝试将TLTransitionLayout与ViewController一起使用。请使用LayoutNavigationTransitions,然后推动转换 [self.navigationController pushViewController:[self nextViewControllerAtPoint:pinchedStackCenter] animated:YES]; 我有两种不同的布局StackedLayout和UICollectionViewFlowLayout,但当我按

我正在尝试将TLTransitionLayout与ViewController一起使用。请使用LayoutNavigationTransitions,然后推动转换

[self.navigationController pushViewController:[self nextViewControllerAtPoint:pinchedStackCenter] animated:YES];
我有两种不同的布局StackedLayout和UICollectionViewFlowLayout,但当我按下视图控制器时,会出现以下错误:

[UICollectionViewFlowLayout setTransitionProgress:]: unrecognized selector sent to instance 0x8f59160
我的控制器实现UINavigationControllerDelegate、APLTransitionManagerDelegate

我把这种转变称为:

- (id <UIViewControllerAnimatedTransitioning> ) navigationController:(UINavigationController *) navigationController
                                 animationControllerForOperation:(UINavigationControllerOperation) operation
                                              fromViewController:(UIViewController *) fromVC
                                                toViewController:(UIViewController *) toVC {
id transitionManager = nil;

// make sure we are transitioning from or to a collection view controller, and that interaction is allowed
if ([fromVC isKindOfClass:[UICollectionViewController class]] &&
    [toVC isKindOfClass:[UICollectionViewController class]] &&
    self.transitionManager.hasActiveInteraction)
{
    self.transitionManager.navigationOperation = operation;
    transitionManager = self.transitionManager;
}
if ([toVC isKindOfClass:[APLGridCollectionViewController class]]) {
    self.transitionLayout = (APLTransitionLayout *)[self.collectionView startInteractiveTransitionToCollectionViewLayout:((APLGridCollectionViewController*)toVC).collectionView.collectionViewLayout completion:^(BOOL completed, BOOL finish) {
        self.collectionView.contentOffset = self.transitionLayout.toContentOffset;
        self.transitionLayout = nil;
        [[UIApplication sharedApplication] endIgnoringInteractionEvents];
    }];
    self.transitionLayout.toContentOffset = [self.collectionView toContentOffsetForLayout:self.transitionLayout indexPaths:@[self.currentPinchedItem] placement:TLTransitionLayoutIndexPathPlacementTop];
    [self.collectionView finishInteractiveTransition];
}
return transitionManager;

因为我希望有两个视图控制器来处理视图的不同需求,并希望每个视图都有不同的导航栏项。

我面临着一个类似的问题-如果能够将TLLayoutTransitioning与UseLayoutLayoutNavigationTransitions混合使用,那就太好了

在iOS7上,可以挂接UINavigationController推送/弹出动画,并通过UINavigationControllerDelegate navigationController:animationControllerForOperation提供您自己的动画:

以下是我迄今为止工作的一些片段

// inside your UINavigationControllerDelegate
- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                   animationControllerForOperation:(UINavigationControllerOperation)operation
                                                fromViewController:(UIViewController *)fromVC
                                                  toViewController:(UIViewController *)toVC
{
  if (![fromVC isKindOfClass:[UICollectionViewController class]] || ![toVC isKindOfClass:[UICollectionViewController class]])
  {
    return nil;
  }

  TransitioningAnimation *animationController;
  animationController = [[TransitioningAnimation alloc] init];

  switch (operation) {
    case UINavigationControllerOperationPush:
      animationController.type = UINavigationControllerOperationPush;
      return  animationController;
    case UINavigationControllerOperationPop:
      animationController.type = UINavigationControllerOperationPop;
      return animationController;
    default: return nil;
  }
}

// another place
@interface TransitioningAnimation : NSObject <UIViewControllerAnimatedTransitioning>
@end

@implementation TransitioningAnimation
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {

  //Get references to the view hierarchy
  UIView *containerView = [transitionContext containerView];
  UICollectionViewController *fromViewController = (UICollectionViewController*)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  UICollectionViewController *toViewController = (UICollectionViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

  UICollectionViewLayout *toLayout = nil;

  if (self.operation == UINavigationControllerOperationPush)
    toLayout = [[SLCollectionViewLargeLayout alloc] init];
  if (self.operation == UINavigationControllerOperationPop)
    toLayout = [[SLCollectionViewSmallLayout alloc] init];

  [containerView insertSubview:toViewController.view aboveSubview:fromViewController.view];

  if (toLayout){

    TLTransitionLayout *layout =  (TLTransitionLayout *)[fromViewController.collectionView transitionToCollectionViewLayout:toLayout
                                                                                                          duration:[self transitionDuration:nil]
                                                                                                            easing:NULL
                                                                                                        completion:^(BOOL completed, BOOL finish) {
                                                                                                          [transitionContext completeTransition:YES];
                                                                                                        }];


    NSArray *selectedIndexPaths = [fromViewController.collectionView indexPathsForSelectedItems];

    CGPoint toOffset = [fromViewController.collectionView toContentOffsetForLayout:layout
                                                       indexPaths:selectedIndexPaths
                                                        placement:TLTransitionLayoutIndexPathPlacementCenter
                                                  placementAnchor:kTLPlacementAnchorDefault
                                                   placementInset:UIEdgeInsetsZero
                                                           toSize:fromViewController.collectionView.bounds.size
                                                   toContentInset:fromViewController.collectionView.contentInset];
    layout.toContentOffset = toOffset;

  }
  else {
    [transitionContext completeTransition:YES];
  }
}

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
  return 0.5;
}
@end

将UseLayoutLayoutNavigationTransitions设置为YES导致的转换不会调用collectionView:TransitionLayoutOutforoldLayout:newLayout:,那么您如何将TLTransitionLayout插入到流程中?我相当确定UseLayoutLayoutNavigationTransitions行为是基于动画的核心转换,因此,不涉及过渡布局。告诉我你想要的TLLayoutTransitioning的具体功能,也许我能帮上忙。嗨,谢谢你的回复。我已经用更多的细节更新了这个问题。看起来您正在尝试执行两个同时发生冲突的转换。由于在animationControllerForOperation中启动的推送和交互转换,您得到了非交互转换。我还没有将TLLayoutTransitioning应用于推送转换,但我知道它需要基于交互式推送转换。非交互式转换是基于核心动画的,这是一种完全不同的动物,不会与StartTinterActivityTransitionToCollectionViewLayout相结合。话虽如此,如果TLLayoutTransition唯一需要的功能是contentOffset控件,我认为您可以将非交互式推送与targetContentOffsetForProposedContentOffset非交互式转换结合使用,并仅使用TLLayoutTransitioning来计算目标内容偏移量。一旦你找到了你想走的路,我很乐意进一步帮助你。
// inside your UINavigationControllerDelegate
- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                   animationControllerForOperation:(UINavigationControllerOperation)operation
                                                fromViewController:(UIViewController *)fromVC
                                                  toViewController:(UIViewController *)toVC
{
  if (![fromVC isKindOfClass:[UICollectionViewController class]] || ![toVC isKindOfClass:[UICollectionViewController class]])
  {
    return nil;
  }

  TransitioningAnimation *animationController;
  animationController = [[TransitioningAnimation alloc] init];

  switch (operation) {
    case UINavigationControllerOperationPush:
      animationController.type = UINavigationControllerOperationPush;
      return  animationController;
    case UINavigationControllerOperationPop:
      animationController.type = UINavigationControllerOperationPop;
      return animationController;
    default: return nil;
  }
}

// another place
@interface TransitioningAnimation : NSObject <UIViewControllerAnimatedTransitioning>
@end

@implementation TransitioningAnimation
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {

  //Get references to the view hierarchy
  UIView *containerView = [transitionContext containerView];
  UICollectionViewController *fromViewController = (UICollectionViewController*)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  UICollectionViewController *toViewController = (UICollectionViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

  UICollectionViewLayout *toLayout = nil;

  if (self.operation == UINavigationControllerOperationPush)
    toLayout = [[SLCollectionViewLargeLayout alloc] init];
  if (self.operation == UINavigationControllerOperationPop)
    toLayout = [[SLCollectionViewSmallLayout alloc] init];

  [containerView insertSubview:toViewController.view aboveSubview:fromViewController.view];

  if (toLayout){

    TLTransitionLayout *layout =  (TLTransitionLayout *)[fromViewController.collectionView transitionToCollectionViewLayout:toLayout
                                                                                                          duration:[self transitionDuration:nil]
                                                                                                            easing:NULL
                                                                                                        completion:^(BOOL completed, BOOL finish) {
                                                                                                          [transitionContext completeTransition:YES];
                                                                                                        }];


    NSArray *selectedIndexPaths = [fromViewController.collectionView indexPathsForSelectedItems];

    CGPoint toOffset = [fromViewController.collectionView toContentOffsetForLayout:layout
                                                       indexPaths:selectedIndexPaths
                                                        placement:TLTransitionLayoutIndexPathPlacementCenter
                                                  placementAnchor:kTLPlacementAnchorDefault
                                                   placementInset:UIEdgeInsetsZero
                                                           toSize:fromViewController.collectionView.bounds.size
                                                   toContentInset:fromViewController.collectionView.contentInset];
    layout.toContentOffset = toOffset;

  }
  else {
    [transitionContext completeTransition:YES];
  }
}

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
  return 0.5;
}
@end