当前位置: 首页 > 面试题库 >

iOS App在PushViewController上冻结

王扬
2023-03-14
问题内容

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

{ [VC-Home, VC-1] }

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

据我所知,导航控制器通过在动画开始之前使先前的视图控制器处于非活动状态来启动动画,但是随后动画从未发生,从而使导航控制器处于冻结状态。

我正在通过调用情节提要创建新的视图控制器, UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController")因此我认为那里没有任何问题。我也没有在导航栏上覆盖pushViewController。我的应用程序的一些独特之处在于,它的图像非常高分辨率(使用SDWebImage进行管理),并且我总是同时在屏幕上拥有三个容器(一个导航控制器,一个用于搜索的视图控制器以及一个交互式装订线/侧面/滑出菜单)。

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

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

更新资料

UINavigationController没有唯一的代码,因为我只是使用pushViewController()进行推送。这是调用它的代码

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

我推送的ViewController在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秒翻阅一次其内容(该应用程序会存储顶部横幅)。在冻结时,我注意到横幅是动画的中期。

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

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)
}

我不记得有发生过动​​画/滚动的情况,因此没有按下过按钮,但是我可能是错的。

我还重新检查了堆栈,并且与上述相同的情况仍然存在,其中[VC-
Home,VC-1]是堆栈,而VC-2没有被推入。我还检查了VC-1的变量,并且一切都已加载(数据调用和图像加载)。

更新3

到第二点,这变得越来越陌生。我已经覆盖了pushViewController,所以可以在其中放置一个断点,并根据Alessandro
Ornano的响应进行一些调试。如果我未成功推送视图控制器,则将我的应用程序发送到后台,在pushViewController调用中放置一个断点,然后再返回该应用程序,该断点将立即被击中多次。如果然后我继续经过所有命中,则下一个视图控制器突然变为可见,并且我尝试推送的最后一个视图控制器现在作为最后一个视图控制器进入堆栈。这意味着我看到的那个人仍然被禁用,这实际上使我处于与以前相同的位置。


问题答案:

几周前,我们遇到了同样的问题。对于我们的问题,我们将其范围缩小到left-edge pop gesture recogniser。您可以尝试使用以下步骤检查是否可以重现此问题

  • 当没有下方的视图控制器时(例如,在根视图控制器上,请尝试使用左边缘弹出手势VC-Home
  • 此后,尝试单击任何UI元素。

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

- (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;
        }
    }
}


 类似资料:
  • 我正在努力理解我的AWS成本报告。我正在开发一个使用AWS进行数据库和存储的社交媒体软件。这个月的成本是250美元,我是该应用程序的唯一用户。这正常吗?我的计划是发布该应用程序并让更多用户加入,但我现在非常害怕。 我正在使用的服务: AppSync/DynamoDB S3 AWSCloudFront 科尼托 我在DynamoDB(AppSync)上有2个表。我将它们转换为全局表,以便其他国家的人也

  • 问题内容: 我有一个非常小的.so文件(可在此处找到:https ://docs.google.com/leaf?id=0B4MxFm- ACB3INjhkMjhlNzktYzkxYy00Zjk5LTk0Y2MtZDE2MWQ2MzY1OWUy &hl=zh_CN& authkey =CMrJguwN) 我试图将其加载到RHEL上的Java中,而Java 只是冻结(没有错误或异常)。我在LD_LI

  • 问题内容: 在遵循一些指南时遇到问题,特别是 http://blog.originate.com/blog/2014/04/22/deeplinking-in- ios/ 我正在设置url方案,并且可以很好地从另一个应用程序启动该应用程序,但是传入主机或url不能正常工作。我正在为所有视图布局使用情节提要和界面生成器。 指南在appDelegate中显示此openURL: 这是我的版本经过简化并从

  • 问题内容: 这是一个片段 我正在使用和作为文本框。文本框应显示“ Hello”,然后等待一秒钟,但是,当我尝试执行此操作时,它会等待一秒钟,然后放置“ Hello”一词,这不是我想要的。 我不确定为什么会这样,因为我将其按逻辑顺序放置。如果有人可以帮助我,那就太好了。 编辑: 有谁知道替代方案,所以我可以使用“延迟”效果吗? 问题答案: 永远不要从Swing事件线程中调用Thread.sleep(

  • 我一直试图使这个应用程序,将产生一个折线图后,我点击"添加新数据项"按钮。现在,在我点击按钮后,什么都没发生(gui冻结),在我最大化框架后,图形出现在框架内,这意味着我的程序工作了,但我不知道为什么我的gui冻结了。我见过类似的问题,人们回答说必须引入一个新的线程来处理不同的拍摄,我也尝试过,但它仍然不起作用,只是让情况变得更糟。有人知道我犯了什么错误吗?这是我的代码: 谢谢你!

  • 问题内容: 美好的一天, 我有一个ServerSocket的无限循环,工作正常…问题是当我尝试使用按钮启动ServerSocket时。我的用户界面“冻结”什么都没有动,但服务器正常运行,这里有一个 ScreenShot : http://i.gyazo.com/15d331166dd3f651fc7bda4e3670be4d.png 当我按下按钮“ Iniciar”表示启动服务器时,用户界面冻结(