菜鸟教程小白 发表于 2022-12-13 05:29:18

ios7 : Custom Push segue pre iOS7 style almost working


                                            <p><p>我尝试制作自定义 segue 来模拟来自 iOS6 的旧 segue 推送,因为新的推送 segue 不适用于我的应用程序。</p>

<pre><code>-(void)perform {

    UIViewController *sourceViewController = (UIViewController*);
    UIViewController *destinationController = (UIViewController*);

    CATransition* transition = ;
    transition.duration = 1.5;
    transition.timingFunction = ;
    transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
    transition.subtype = kCATransitionFromRight; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom



    [sourceViewController.navigationController.view.layer addAnimation:transition
                                                                forKey:kCATransition];

    ;

}
</code></pre>

<p>一切都嵌入在导航 Controller 中。我已将延伸边缘标记为“在顶部栏下方”和“在底部栏下方”。而且我在两个 ViewController (源和目标)中都有 View 的自定义背景颜色。在这两个 ViewController 之间的过渡期间,导航栏开始在白色和两个 ViewController 的自定义背景颜色之间闪烁。知道为什么吗?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>你的代码中的问题是这样的:</p>

<p>当你触发 <code>pushViewController</code> 方法时,<code>sourceViewController</code> 立即从导航堆栈中移除,<code>destinationViewController</code> 出现。
这会导致动画出现问题(即使在 iOS 6 上也存在问题,导致另一个问题,即“黑色渐变”)。
如果您仍想使用 <code>pushViewController</code> (这更容易,因为您不需要重建导航逻辑),您必须按照 Apple <a href="https://developer.apple.com/library/ios/documentation/uikit/reference/UIStoryboardSegue_Class/Reference/Reference.html#//apple_ref/occ/instm/UIStoryboardSegue/perform" rel="noreferrer noopener nofollow">here</a> 的建议进行操作</p>

<blockquote>
<p>Regardless of how you perform the animation, at the end of it, you are responsible for installing the destination view controller (and its views) in the right place so that it can handle events. For example, if you were to implement a custom modal transition, you might perform your animations using snapshot images and then at the end call the presentModalViewController:animated: method (with animations disabled) to set up the appropriate modal relationship between the source and destination view controllers.</p>
</blockquote>

<p>您应该使用快照。</p>

<p>这里你的 perform 方法更新了:</p>

<pre><code>- (void)perform
{
    UIViewController *source = (UIViewController *) self.sourceViewController;
    UIViewController *destination = (UIViewController *) self.destinationViewController;

    // Swap the snapshot out for the source view controller
    UIWindow *window = source.view.window;
    UIImageView *screenShot = [ initWithImage:];

    BOOL animsEnabled = ;
    ;

    ;

    ;

    CATransition* transition = ;
    transition.duration = 1.5;
    transition.timingFunction = ;
    transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
    transition.subtype = kCATransitionFromRight; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
    ;
    ;


    [UIView animateWithDuration:1.5f animations:^{
      screenShot.frame = CGRectOffset(screenShot.frame, -screenShot.frame.size.width, 0);
    } completion:^(BOOL finished) {
      ;
    }];
}
</code></pre>

<p>要做出正确的截图,仅仅使用 <code>renderInContext</code> 方法是不够的,因为半透明条的模糊没有正确管理。
我找到了另一种方法(从 <a href="https://stackoverflow.com/questions/7964153/ios-whats-the-fastest-most-performant-way-to-make-a-screenshot-programaticall" rel="noreferrer noopener nofollow">THIS</a> 问题复制和粘贴)</p>

<pre><code>- (UIImage *)screenshot
{
    CGSize imageSize = CGSizeZero;

    UIInterfaceOrientation orientation = .statusBarOrientation;
    if (UIInterfaceOrientationIsPortrait(orientation)) {
      imageSize = .bounds.size;
    } else {
      imageSize = CGSizeMake(.bounds.size.height, .bounds.size.width);
    }

    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    for (UIWindow *window in [ windows]) {
      CGContextSaveGState(context);
      CGContextTranslateCTM(context, window.center.x, window.center.y);
      CGContextConcatCTM(context, window.transform);
      CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
      if (orientation == UIInterfaceOrientationLandscapeLeft) {
            CGContextRotateCTM(context, M_PI_2);
            CGContextTranslateCTM(context, 0, -imageSize.width);
      } else if (orientation == UIInterfaceOrientationLandscapeRight) {
            CGContextRotateCTM(context, -M_PI_2);
            CGContextTranslateCTM(context, -imageSize.height, 0);
      } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
            CGContextRotateCTM(context, M_PI);
            CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
      }
      if () {
            ;
      } else {
            ;
      }
      CGContextRestoreGState(context);
    }

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
</code></pre>

<p>我附上了一个示例项目,展示了它是如何工作的:<a href="http://www.lombax.it/Documents/CustomSeguePush.zip" rel="noreferrer noopener nofollow">Link to sample project</a> </p></p>
                                   
                                                <p style="font-size: 20px;">关于ios7 : Custom Push segue pre iOS7 style almost working,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/19978130/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/19978130/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios7 : Custom Push segue pre iOS7 style almost working