【问题标题】:UITableViewCell selection Storyboard segue is slow - double tapping works thoughUITableViewCell 选择 Storyboard segue 很慢 - 虽然双击有效
【发布时间】:2014-11-27 17:31:18
【问题描述】:

我在 Storyboard 中有一个 UITableViewController。我选择了我的 UITableViewCell 原型触发一个 segue 来呈现另一个控制器。演示文稿本身正在运行。

我注意到一个奇怪的错误(可能在 iOS 8 中引入),点击单元格会按预期突出显示单元格,但有时需要几秒钟才能执行转场。点击单元格两次会立即发生转场。

有其他人在 iOS 8 中注意到这一点吗?

编辑:我现在注意到不仅仅是双击可以更快地触发 segue。它也是在单元格上点击,然后在任何地方滑动。开始对我来说似乎是一个线程问题......

【问题讨论】:

  • 没有任何代码,只是在情节提要中继续?如果在didSelectRow 上添加performSegue 会发生什么? PS:我讨厌使用 segue,我添加它们的唯一原因是为了标记应用程序的流程。
  • 是的,我会发布代码,但基本上没有。试过你说的,同样的问题。
  • 你一定在做点什么。我测试了旧项目并创建了一个新项目,但是选择和推送之间没有延迟,就像在 iOS8 之前一样。
  • 我有同样的问题,我不明白为什么会这样。我尝试过不同的 segue 和 performSegue,但没有解决问题。这只发生在 Table View Cell selection 设置为 none 时,否则工作正常。
  • 我发布了最终解决我案件的方法。感谢@LordZsolt 再次尝试的灵感。

标签: objective-c uitableview storyboard ios8


【解决方案1】:

就我而言,解决方案最终是使用 GCD 从主队列上的 didSelectRow 手动调用 performSegue,而不是使用 Storyboard 中的 UITableViewCell 选择出口。

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  dispatch_async(dispatch_get_main_queue(), ^{
    [self performSegueWithIdentifier:kShowDetailSegue
                          sender:nil];
  });
}

我不知道为什么这变得必要 - 当然你会认为 Storyboard 中的选择出口会在主队列上运行,但可能是 iOS 8 的错误。

【讨论】:

  • 如果您希望此 segue 的行为方式与原始 segue 相同。而不是sender:nil 使用sender:[tableView cellForRowAtIndexPath:indexPath]。这意味着在准备 segue 时,您可以使用 sender 来确定 indexPath,这在设置目标视图控制器时通常是必需的。
  • 我遇到了类似的问题,以编程方式调用 performSegueWithIdentifier 在实际加载下一个视图之前需要花费 10 多秒的时间。不确定幕后发生了什么样的线程废话,但在主队列上调度也解决了我的问题。对于它的价值,我正在大量使用多点连接(而不是真正的其他);不确定这是否相关。
  • 很遗憾,Apple 尚未修复此错误!在 iOS 9 中仍然会发生!
  • iOS 10.3,错误仍然存​​在。空白项目,只有带有基本单元格的 UITableViewController 和 VC 可以继续。将单元格属性“选择”设置为无,有时会导致不调用 segue 的问题(通常在滚动表之后)。 didSelectRow 总是被调用。 Segue 直接从单元连接到另一个 VC。只需将 DispatchQueue.main.async {}(传递空块)放入 didSelectRow 即可解决此问题。
【解决方案2】:

Carlos Vela 是对的,只有当 UITableViewCell 选择为无且仅在真实设备上时才会出现该错误。选择后唤醒 CFRunLoop 解决了问题,这让我想到了这个“通用”解决方法(这是 UITableViewCell 上的一个类别)。

更新:它在 iOS7 下完美运行,但在 iOS8 下它破坏了透明的 UITableViewCell 背景(它将是白色的)。

#import <objc/runtime.h>

@implementation UITableViewCell (WYDoubleTapFix)

+ (void)load
{
    Method original, swizzled;

    original = class_getInstanceMethod([UITableViewCell class], @selector(setSelected:animated:));
    swizzled = class_getInstanceMethod([UITableViewCell class], @selector(mySetSelected:animated:));
    method_exchangeImplementations(original, swizzled);
}

- (void)mySetSelected:(BOOL)selected animated:(BOOL)animated
{
    [self mySetSelected:selected animated:animated];
    CFRunLoopWakeUp(CFRunLoopGetCurrent());
}

@end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多