【问题标题】:UIActivityViewController taking long time to presentUIActivityViewController 需要很长时间才能呈现
【发布时间】:2012-12-04 03:15:03
【问题描述】:

我为 iPhone 制作了一个应用程序。现在,我正在为 iPad 重新创建它。

当用户选择工具栏中的操作按钮时,弹出框应显示UIActivityViewController,但由于某种原因,第一次显示大约需要 10 秒。在 iPhone 上,大约需要一秒钟。除了弹出框之外,它是相同的代码。

我尝试禁用弹出框,但仍然需要大约 10 秒才能显示。

代码如下:

-(IBAction)Actions:(UIBarButtonItem*)sender 
{
    if ([activityPopover isPopoverVisible] == YES) 
    {
        [activityPopover dismissPopoverAnimated:YES];
        return;
    }
    UIWebView *currentWebView = ((TabView *)self.tabs[self.currentTabIndex]).webViewObject;

    NSString *currentURL = (NSString*)[currentWebView request].mainDocumentURL;
    if (currentURL == NULL) return;

    BookmarkActivity *bookmarkActivity = [[BookmarkActivity alloc] init];

    UIActivityViewController *sharing = [[UIActivityViewController alloc] initWithActivityItems:[NSArray arrayWithObject:currentURL] applicationActivities:@[bookmarkActivity]];

    activityPopover = [[UIPopoverController alloc] initWithContentViewController:sharing];
    [activityPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];    
}

我已经在我的 iPad 3 和 iPad mini 上进行了测试,都需要一段时间来展示这个。

我该如何解决这个问题?

【问题讨论】:

  • 你用时间分析器测试过吗?您可能会发现最耗时的指令是什么。
  • 按 cmd+I 然后选择时间分析器。等待 10-20 秒。然后选中“隐藏系统库”选项。这将使您在调用堆栈中更好地查看您的方法。找到您的调用栈中的方法,点击两次,就可以看到耗时了。
  • 您应该会看到类似这样的内容:imageshack.us/f/803/screenshot20121217at235.png 告诉我们耗时或发布图片。
  • activityPopover = [[UIPopoverController alloc] initWithContentViewController:sharing]; 上表示 85.7%,[activityPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; 上表示 13.1% 和 BookmarkActivity *bookmarkActivity = [[BookmarkActivity alloc] init]; 上表示 1.2%
  • 我没有,第一次由于某种原因仍然很慢,然后每次都很快。

标签: ios objective-c uipopovercontroller uiactivityviewcontroller


【解决方案1】:

我自己最近遇到了这个问题。有时会需要将近 4 或 5 秒才能弹出,这是一生!不过也只是第一次。随后的电话很快。

几年前也遇到过类似的问题,键盘出现缓慢,有人编写了几行代码添加到预加载键盘的 appdelegate 中以解决这个问题。

我在这里使用了类似的方法来预加载 UIActivityViewController,方法是在启动时将它放在 AppDelegate 中。这绝对是一个不必要的 hack,但我找不到任何其他选项。

let lagfreeAVC:UIActivityViewController = UIActivityViewController(activityItems:  ["start"], applicationActivities: nil)
lagfreeAVC.becomeFirstResponder()
lagfreeAVC.resignFirstResponder()

【讨论】:

  • 确实提高了 ActivityViewController 的加载时间,但我不确定这是否会影响应用程序的加载时间。
【解决方案2】:

好问题,我也遇到了同样的问题。这并不是真正可以解决的。但是,您可以通过创建一个活动指示器,然后将 UIActivityViewController 的初始化发送到后台来改善用户体验:

-(void)openIn:(id)sender
{
    // start activity indicator
    [self.activityIndicator startAnimating];

    // create new dispatch queue in background
    dispatch_queue_t queue = dispatch_queue_create("openActivityIndicatorQueue", NULL);

    // send initialization of UIActivityViewController in background
    dispatch_async(queue, ^{
        NSArray *dataToShare = @[@"MyData"];
        UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:nil];

        // when UIActivityViewController is finally initialized, 
        // hide indicator and present it on main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.activityIndicator stopAnimating];
            [self presentViewController:activityViewController animated:YES completion:nil];
        });
    });
}

它就像一个魅力。当用户触摸按钮时,活动指示器开始动画,从而表明该过程需要一段时间。

【讨论】:

  • 我建议相同,但以更优雅的方式。将UIBarButtonItem 属性customView 设置为动态创建的UIActivityIndicator。这会将按钮图标替换为活动指示器。然后,在演示动画的完成块上调用[button setCustomView:nil],它将恢复为原始样式。 =)
  • @BrunoPhilip 在 iOS 7.0.3 上对使用系统图标创建的 UIBarButtonItem 调用 setCustomView:nil 似乎会完全删除该图标。
  • @zeckel 我正在使用 iOS 7.1 beta 的应用程序,它可以正常工作。也许是别的东西?如果您的按钮在进行替换之前使用了自定义视图,则您需要将其替换回来,而不是将其设置为nil。尝试检查customView 的先前值。
  • 像魅力一样工作!
【解决方案3】:

虽然这些调用已经来自主线程,但从 iOS 7 开始,将其中一些演示调用包装在一个调度块中似乎可以大大减少延迟

dispatch_async(dispatch_get_main_queue(), ^{
    [self presentViewController:activityViewController animated:YES completion:nil];
});

【讨论】:

  • 你测量了吗?我几乎无法理解这应该如何工作,因为它只是在主循环的下一次迭代中运行演示文稿,即实际上 稍后 与您直接调用它时相比。 困惑
【解决方案4】:

我在 iOS 7 上遇到了同样的问题。但是,当我从允许的活动类型中删除 UIActivityTypeAirDrop 时,控制器几乎立即出现。

【讨论】:

  • 这很奇怪,很遗憾 Apple 没能做到这么快:谢谢!
  • 比以前快了,但还是很慢
  • 对应代码:UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil]; activityController.excludedActivityTypes = @[UIActivityTypeAirDrop];
猜你喜欢
  • 2019-09-12
  • 1970-01-01
  • 2017-09-07
  • 2013-10-11
  • 2012-12-03
  • 2014-07-21
  • 2019-10-26
  • 2012-06-24
  • 2013-11-15
相关资源
最近更新 更多