You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 14中自定义视图控制器转场的Transform处理是否有变更?

iOS 14 UIPresentationController Transform Changes & Fix for Modal Transition Replication

Hey there, let's break down what's going on with your UIPresentationController transform issue on iOS 14. First off—yes, Apple did tweak how transforms are handled for presenting view controllers in iOS 14, particularly around animation context timing and coordinate system references, which is likely causing that weird jump you're seeing during dismissal.

What Changed in iOS 14?

iOS 14 introduced adjustments to how the system manages the presenting view controller's layout and animation during modal transitions. Some key shifts include:

  • Coordinate system alignment: The system now prioritizes the container view's bounds over screen bounds for layout calculations in UIPresentationController, which can throw off transforms that rely on UIScreen.main.bounds.
  • Animation phase timing: During dismissal, the system may reset the presenting view's transform earlier in the animation cycle than in iOS 13, leading to intermediate position jumps before settling on the correct final state.
  • Anchor point assumptions: The default anchor point (0.5, 0.5) for the presenting view's layer can cause unexpected shifts when scaling, as iOS 14's layout system handles view positioning relative to the container more strictly.

Fixing Your Transform Code

Let's adjust your transform logic to align with iOS 14's behavior. Here are the key changes to implement:

  1. Use container view bounds instead of screen bounds
    Stop relying on UIScreen.main.bounds—your presentation controller's container view is the correct reference frame, as it accounts for safe areas and container layout changes.

  2. Adjust the presenting view's anchor point
    Set the anchor point to the bottom center of the presenting view to match the system's native modal transition scaling behavior, which eliminates jumpy positioning during animation.

  3. Refine the translation calculation
    Tweak the translation offset to account for iOS 14's animation context timing.

Here's the updated code:

override func presentationTransitionWillBegin() {
    super.presentationTransitionWillBegin()
    
    // Set anchor point to bottom center for natural scaling
    guard let presentingView = presentingViewController.view else { return }
    presentingView.layer.anchorPoint = CGPoint(x: 0.5, y: 1.0)
    // Update frame to compensate for anchor point change
    presentingView.frame = presentingView.superview?.bounds ?? presentingView.frame
}

override func frameOfPresentedViewInContainerView() -> CGRect {
    guard let containerView = containerView else { return super.frameOfPresentedViewInContainerView() }
    
    // Calculate presented view frame based on container bounds
    let horizontalPadding: CGFloat = 16
    let width = containerView.bounds.width - (horizontalPadding * 2)
    let height = containerView.bounds.height
    let originY = (containerView.bounds.height - height) / 2
    
    return CGRect(x: horizontalPadding, y: originY, width: width, height: height)
}

override func transformForPresentedView() -> CGAffineTransform {
    guard let containerView = containerView else { return .identity }
    
    let ratio = (containerView.bounds.width - 32) / containerView.bounds.width
    let presentingViewHeight = containerView.bounds.height
    let scaledHeight = presentingViewHeight * ratio
    // Adjust translation to match iOS 14's animation context
    let translationY = (presentingViewHeight - scaledHeight) / 2 + 10
    
    return CGAffineTransform(scaleX: ratio, y: ratio)
        .concatenating(CGAffineTransform(translationX: 0, y: translationY))
}

Additional Checks

  • Verify dismiss animation timing: If you're using a custom animator, ensure you're using UIViewPropertyAnimator with the transition context's duration and curve, rather than hardcoding animation parameters. This ensures alignment with iOS 14's system animation timing.
  • Avoid cached values: Don't cache frameOfPresentedViewInContainerView results—calculate it dynamically each time it's needed, as the container view's bounds can change during rotation or layout updates.

These changes should eliminate the dismissal jump you're seeing, while keeping your transition consistent across iOS 12, 13, and 14.

内容的提问来源于stack exchange,提问作者okoroezenwa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:13:12