ios - 当高度改变时 UINavigationController 会切断内容吗? (动图)

标签 ios swift uiviewcontroller uinavigationcontroller ios-animations

我已将 UINavigationController 放入可扩展的“抽屉”中。 我的目标是让导航堆栈中的每个 viewController 都有自己的“首选”高度。

假设 VC1 需要很高。当从 VC2 导航回 VC1 时,我希望它的动画高度变高。即使有滑动交互,动画逻辑似乎也能正常工作。

但是由于某种原因,navigationController中的viewController被“切断”了。他们的约束是正确的,但没有更新(?)。或者,在我再次触摸 View 之前,部分内容根本不会呈现。底部的不可见区域甚至可以接受触摸。

看一下:

gif

预期结果是 contentViewController(第一个和第二个)始终延伸到屏幕底部。他们被限制这样做,所以问题是他们在转换期间不会“渲染”(?)。

在 UINavigationController 的委托(delegate)中,我执行以下操作:

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
    transitionCoordinator?.animate(alongsideTransition: { (context) in
            drawer.heightConstraint.constant = targetHeight
            drawer.superview?.layoutIfNeeded()
        }, completion: { (context) in
            print("done")
        })
}

高度变化很完美。但导航中的内容不符合要求。 navigationController 被限制为前导、尾随、底部和一个存储的 heightConstraint,该 heightConstraint 会更改其常量。

一旦我触摸/拖动导航 Controller /内容,它就会立即“渲染未渲染的”,一切都很好。为什么会发生这种情况?

当检查 View 层次结构时,它看起来像这样:

enter image description here

NavigationController 的高度已达到所需高度,但内容与过渡开始时整个抽屉的高度相同,并且直到我触摸它时它才会更新。 为什么?

编辑:我已将代码推送到 my GitHub如果你想看一下。但请注意,还有其他几个问题(动画等),不要介意它们。我只想知道为什么导航不会呈现“ future ”的高度。

最佳答案

您可以通过为navigationController使用自定义animationController并在自定义UIViewControllerAnimatedTransitioning实现的animateTransition函数中为destinationView设置适当的框架来解决上述问题。结果将如下面的 gif 图像所示。

enter image description here

您的自定义 UIViewControllerAnimatedTransitioning 可能如下所示。

final class TransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    let presenting: Bool

    init(presenting: Bool) {
        self.presenting = presenting
    }

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return TimeInterval(UINavigationController.hideShowBarDuration)
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromView = transitionContext.view(forKey: .from) else { return }
        guard let toView = transitionContext.view(forKey: .to) else { return }

        let duration = transitionDuration(using: transitionContext)

        let container = transitionContext.containerView
        if presenting {
            container.addSubview(toView)
        } else {
            container.insertSubview(toView, belowSubview: fromView)
        }

        let toViewFrame = toView.frame
        toView.frame = CGRect(x: presenting ? toView.frame.width : -toView.frame.width, y: toView.frame.origin.y, width: toView.frame.width, height: toView.frame.height)

        UIView.animate(withDuration: duration, animations: {
            toView.frame = toViewFrame
            fromView.frame = CGRect(x: self.presenting ? -fromView.frame.width : fromView.frame.width, y: fromView.frame.origin.y, width: fromView.frame.width, height: fromView.frame.height)
        }) { (finished) in
            container.addSubview(toView)
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
}

并且,在您的导航 Controller 中提供自定义动画 Controller ,如下所示。

func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
   switch operation {
   case .push:
      return TransitionAnimator(presenting: true)
   case .pop:
      return TransitionAnimator(presenting: false)
   default:
      return nil
   }
}

PS:- 我还在您的 github 存储库中提出了拉取请求。

关于ios - 当高度改变时 UINavigationController 会切断内容吗? (动图),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59124702/

相关文章:

ios - iOS7 deleteSections:withRowAnimation:删除最后一节时的动画错误

ios - 为什么 [UIBarButtonItem setCustomView :] method disable segue in Storyboard?

ios - 无法将 UIScrollView 添加到 View 的一部分

ios - 为不同的 Controller 重用 View 的最佳方式

ios - 如何使 View 始终在应用程序的屏幕上可见?

iphone - 如何从表格 View 单元格中搜索数据?

ios - dyld:未加载库:libperl.dylib 引用自:perl5.18

ios - 无法将我的 iOS 应用程序扩展到 iPhone 5 和 4

swift - 如何在协议(protocol)扩展中定义初始值设定项?

arrays - 在 Swift 中用空项目对数组进行升序排序