iOS App冻结在PushViewController上 [英] iOS App Freezes on PushViewController

查看:299
本文介绍了iOS App冻结在PushViewController上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的导航控制器间歇性地会在推送时冻结。它似乎将新的视图控制器添加到堆栈中,但动画永远不会发生。我还有两个其他容器在屏幕上保存视图控制器,我可以在导航控制器冻结后很好地与它们进行交互。真正有趣的是,如果我尝试将另一个视图控制器推到导航控制器的堆栈上,我注意到堆栈顶部有一个额外的视图控制器(我最初推动的视图控制器冻结了导航控制器)。因此,如果我在主屏幕上(我们将其称为VC-Home)并尝试推送新视图(VC-1)并冻结,那么我尝试推送新视图(VC-2),这是我在推送之前在当前堆栈中看到的:

My navigation controller intermittently will freeze on push. It seems to add the new view controller onto the stack, but the animation never takes place. I also have two other containers that hold view controllers on the screen, and I can interact with both of them just fine after the navigation controller freezes. The really interesting thing is if I try to push another view controller onto the navigation controller's stack, I noticed that there is an extra view controller on top of the stack (the view controller that I pushed initially that froze the navigation controller). So if I'm on the home screen (we'll call it VC-Home) and I try to push a new view (VC-1) and it freezes, then I try to push a new view (VC-2), this is what I see in the current stack before the push:

{[VC-Home,VC-1]}

并且在调用pushViewController之后,它保持不变; VC-2没有添加到堆栈中。

and after pushViewController is called, it remains the same; VC-2 is not added to the stack.

据我所知,导航控制器通过在动画开始之前使前一个视图控制器处于非活动状态来启动动画,但是然后动画永远不会发生,让导航控制器处于冻结状态。

From what I can tell, the navigation controller starts the animation by making the previous view controller inactive before the animation begins, but then the animation never takes place, leaving the navigation controller in a frozen state.

我正在通过调用
UIStoryboard(名称:Main,bundle:nil)从故事板创建新的视图控制器.instantiateViewControllerWithIdentifier(ViewController)所以我认为那里没有任何问题。我也没有在导航栏上覆盖pushViewController。关于我的应用程序的一些独特之处在于它的图像非常高(使用SDWebImage来管理)并且我一次在屏幕上有三个容器(一个导航控制器,一个用于搜索的视图控制器和一个交互式装订线/侧面/滑出菜单)。

I'm creating the new view controller from a storyboard by calling UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") so I don't think there's any issues there. I'm also not overriding pushViewController on the navigation bar. Some unique things about my app is that it is very high-res image heavy (using SDWebImage to manage that) and I always have three containers on the screen at once (one navigation controller, one view controller for search, and one interactive gutter/side/slideout menu).

CPU使用率低且内存使用率正常(发生冻结时设备稳定在60-70MB左右)。

CPU usage is low and memory usage is normal (steadily around 60-70MB on device when freezes occur).

是否有任何想法可能导致此问题或任何调试技巧可以帮助我发现真正的问题?

Are there any ideas with what might be causing this or any debugging tips that could help me discover the real problem?

更新

UINavigationController没有唯一的代码,因为我只是推动使用pushViewController()。以下是调用它的代码:

There's no unique code for the UINavigationController since I'm just pushing using pushViewController(). Here's the code that calls it:

func didSelectItem(profile: SimpleProfile) {
     let vc = UIStoryboard.profileViewController()
     vc.profile = profile
     navigationController?.pushViewController(vc, animated: true)
}

我推送的ViewController在viewDidLoad中有以下代码:

The ViewController that I pushed has the following code in viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
    button.roundView()

    if let type = profile?.profileType {
        //load multiple view controllers into a view pager based on type 
        let viewControllers = ProfileTypeTabAdapter.produceViewControllersBasedOnType(type)
        loadViewPagerViews(viewControllers)

        let topInset = headerView.bounds.height + tabScrollView.contentSize.height
        if let viewPager = viewPager {
            for view in viewPager.views {
                if let tempView = view as? PagingChildViewController {
                    tempView.profile = fullProfile
                    tempView.parentVCDelegate = self
                    tempView.topInset = topInset
                }
            }
        }
    }
}

func loadViewPagerViews(viewControllers: [UIViewController]) {
    viewPager?.views = viewControllers
    viewPager?.delegate = self

    //loading views into paging scroll view (using PureLayout to create constraints)
    let _ = subviews.map { $0.removeFromSuperview() }
    var i = 0
    for item in views {
        addSubview(item.view)
        item.view.autoSetDimensionsToSize(CGSize(width: tabWidth, height: tabHeight))
        if i == 0 {
            item.view.autoPinEdgeToSuperviewEdge(.Leading)
        } else if let previousView = views[i-1].view {
            item.view.autoPinEdge(.Leading, toEdge: .Trailing, ofView: previousView)
        }
        if i == views.count {
            item.view.autoPinEdgeToSuperviewEdge(.Trailing)
        }
        i += 1
    }

    contentSize = CGSize(width: Double(i)*Double(tabWidth), height: Double(tabHeight))
}

更新2

我终于让它再次冻结。该应用程序在后台,我把它带回来,尝试在冻结时推动堆栈上的视图控制器。我注意到一个动画正在发生。我在页面顶部有一个滚动视图,每10秒翻阅一次内容(想想应用程序存储顶部横幅)。在这个冻结中,我注意到横幅是动画中期。

I finally got it to freeze again. The app was in the background and I brought it back and tried pushing a view controller on the stack when it froze. I noticed an animation was taking place. I have a scrollview at the top of the page that pages through its content every 10 seconds (think of the app stores top banner). On this freeze, I noticed that the banner was mid-animation.

这是来自我的UIScrollView的滚动功能,每10秒调用一次:

Here's the scrolling function from the my UIScrollView that gets called every 10 seconds:

func moveToNextItem() {
    let pageWidth: CGFloat = CGRectGetWidth(frame)
    let maxWidth: CGFloat = pageWidth * CGFloat(max(images.count, profileImages.count))
    let contentOffset: CGFloat = self.contentOffset.x
    let slideToX = contentOffset + pageWidth

    //if this is the end of the line, stop the timer
    if contentOffset + pageWidth == maxWidth {
        timer?.invalidate()
        timer = nil
        return
    }

    scrollRectToVisible(CGRectMake(slideToX, 0, pageWidth, CGRectGetHeight(frame)), animated: true)
}

我不记得有过由于动画/滚动发生推动停止,但我可能是错的。

I don't recall ever having a push stop because of an animation/scroll taking place, but I could be wrong.

我还重新检查了堆栈,并且上述相同的情况仍然是情况在哪里[VC-Home,VC-1]是堆栈,VC-2没有按下。我还浏览了VC-1的变量,所有内容都已加载(数据调用和图像加载)。

I've also rechecked the stack and the same situation as described above is still the case where [VC-Home, VC-1] is the stack and VC-2 is not pushed on. I've also gone through VC-1's variables and everything has loaded (data calls and image loads).

更新3

这是第二次变得陌生。我已经覆盖了pushViewController,所以我可以在那里放置一个断点并根据Alessandro Ornano的响应做一些调试。如果我推送视图控制器失败,然后将我的应用程序发送到后台,将一个断点放入pushViewController调用,并将应用程序恢复,断点会立即被多次击中。如果我然后继续经过所有命中,下一个视图控制器突然变得可见,我试图推送的最后一个视图控制器现在作为最后一个视图控制器在堆栈上。这意味着我看到的那个仍然被禁用,这实际上使我处于与以前相同的位置。

This is getting stranger by the second. I've overriden pushViewController so I can put a breakpoint in there and do some debugging based on Alessandro Ornano's response. If I push a view controller unsuccessfully, then send my app to the background, put a breakpoint into the pushViewController call, and bring the app back, the breakpoint is immediately hit a number of times. If I then continue past all the hits, the next view controller suddenly becomes visible and the last view controller I tried to push is now on the stack as the last view controller. This means that the one that I see is still disabled, which essentially puts me in the same position as before.

推荐答案

我们有几个星期后面临同样的问题。对于我们的问题,我们将其缩小到左边的流行手势识别器。您可以尝试使用以下步骤检查是否可以重现此问题

We have faced the same problem couple of weeks back. And for our problem we narrowed it down to left-edge pop gesture recogniser. You can try and check if you can reproduce this problem using below steps


  • 如果下面没有视图控制器,请尝试使用左边缘弹出手势它(即在根视图控制器上,你的 VC-Home 控制器)

  • 在此之后尝试点击任何UI元素。

  • Try using the left edge pop gesture when there are no view controllers below it (i.e on root view controllers, your VC-Home controller)
  • Try clicking on any UI elements after this.

如果您能够重现冻结,请尝试在视图控制器时禁用 interactivePopGestureRecognizer 堆栈只有一个视图控制器。

If you are able to reproduce the freeze, try disabling the interactivePopGestureRecognizer when the view controller stack have only one view controller.

请参阅这个问题了解更多详情。以下是链接中的代码,以便于参考。

Refer to this question for more details. Below is the code from the link for ease of reference.

- (void)navigationController:(UINavigationController *)navigationController
   didShowViewController:(UIViewController *)viewController
                animated:(BOOL)animate
{
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
        if (self.viewControllers.count > 1)
        {
            self.interactivePopGestureRecognizer.enabled = YES;
        }
        else
        {
            self.interactivePopGestureRecognizer.enabled = NO;
        }
    }
}

这篇关于iOS App冻结在PushViewController上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆