gpt4 book ai didi

ios - 在 transitionWithView 中更改 rootViewController 时泄漏 View

转载 作者:IT王子 更新时间:2023-10-29 07:30:05 24 4
gpt4 key购买 nike

在调查内存泄漏时,我发现了一个与在过渡动画 block 中调用 setRootViewController: 技术相关的问题:

[UIView transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ self.window.rootViewController = newController; }
completion:nil];

如果旧的 View Controller (被替换的那个)当前呈现另一个 View Controller ,那么上面的代码不会从 View 层次结构中删除呈现的 View 。

也就是这个操作序列...

  1. X 成为 Root View Controller
  2. X 呈现 Y,因此 Y 的 View 显示在屏幕上
  3. 使用 transitionWithView: 使 Z 成为新的 Root View Controller

...对用户来说看起来没问题,但是调试 View 层次结构工具会显示 Y 的 View 仍然在 Z 的 View ​​后面,在 UITransitionView 中。即经过上述三步后, View 层级为:

  • 用户界面窗口
    • UITransitionView
      • UIView(Y 的 View )
    • UIView(Z 的 View ​​)

我怀疑这是个问题,因为在转换时,X 的 View 实际上并不是 View 层次结构的一部分。

如果我在 transitionWithView: 之前立即向 X 发送 dismissViewControllerAnimated:NO,则生成的 View 层次结构为:

  • 用户界面窗口
    • UIView(X 的 View )
    • UIView(Z 的 View ​​)

如果我将 dismissViewControllerAnimated:(是或否)发送到 X,然后在 completion: block 中执行转换,则 View 层次结构是正确的。不幸的是,这会干扰动画。如果动画解雇,那会浪费时间;如果没有动画,它看起来就坏了。

我正在尝试一些其他方法(例如,制作一个新的容器 View Controller 类作为我的 Root View Controller )但没有找到任何可行的方法。我会随时更新这个问题。

最终目标是直接从呈现的 View 过渡到新的 Root View Controller ,而不会留下杂散的 View 层次结构。

最佳答案

我最近遇到了类似的问题。我不得不从窗口中手动删除那个 UITransitionView 来解决这个问题,然后在之前的 Root View Controller 上调用 dismiss 以确保它被释放。

修复不是很好,但除非您在发布问题后找到更好的方法,否则这是我发现的唯一可行的方法! viewController 只是您原始问题中的 newController

UIViewController *previousRootViewController = self.window.rootViewController;

self.window.rootViewController = viewController;

// Nasty hack to fix http://stackoverflow.com/questions/26763020/leaking-views-when-changing-rootviewcontroller-inside-transitionwithview
// The presenting view controllers view doesn't get removed from the window as its currently transistioning and presenting a view controller
for (UIView *subview in self.window.subviews) {
if ([subview isKindOfClass:NSClassFromString(@"UITransitionView")]) {
[subview removeFromSuperview];
}
}
// Allow the view controller to be deallocated
[previousRootViewController dismissViewControllerAnimated:NO completion:^{
// Remove the root view in case its still showing
[previousRootViewController.view removeFromSuperview];
}];

我希望这也能帮助您解决问题,这绝对是个麻烦!

Swift 3.0

(查看其他 Swift 版本的编辑历史)

为了更好地实现作为 UIWindow 的扩展,允许传入可选的转换。

extension UIWindow {

/// Fix for http://stackoverflow.com/a/27153956/849645
func set(rootViewController newRootViewController: UIViewController, withTransition transition: CATransition? = nil) {

let previousViewController = rootViewController

if let transition = transition {
// Add the transition
layer.add(transition, forKey: kCATransition)
}

rootViewController = newRootViewController

// Update status bar appearance using the new view controllers appearance - animate if needed
if UIView.areAnimationsEnabled {
UIView.animate(withDuration: CATransaction.animationDuration()) {
newRootViewController.setNeedsStatusBarAppearanceUpdate()
}
} else {
newRootViewController.setNeedsStatusBarAppearanceUpdate()
}

if #available(iOS 13.0, *) {
// In iOS 13 we don't want to remove the transition view as it'll create a blank screen
} else {
// The presenting view controllers view doesn't get removed from the window as its currently transistioning and presenting a view controller
if let transitionViewClass = NSClassFromString("UITransitionView") {
for subview in subviews where subview.isKind(of: transitionViewClass) {
subview.removeFromSuperview()
}
}
}
if let previousViewController = previousViewController {
// Allow the view controller to be deallocated
previousViewController.dismiss(animated: false) {
// Remove the root view in case its still showing
previousViewController.view.removeFromSuperview()
}
}
}
}

用法:

window.set(rootViewController: viewController)

或者

let transition = CATransition()
transition.type = kCATransitionFade
window.set(rootViewController: viewController, withTransition: transition)

关于ios - 在 transitionWithView 中更改 rootViewController 时泄漏 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26763020/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com