【问题标题】:UITextViews in a UITableView link detection bug in iOS 7iOS 7 中的 UITableView 链接检测错误中的 UITextViews
【发布时间】:2013-10-07 22:03:00
【问题描述】:

我有包含 UITextView 的自定义 UITableViewCells。我在 Interface Builder 中打开了 UITextView 中的链接检测。当我第一次加载表格视图时,一切似乎都在工作,但是当我上下滚动表格视图时,链接检测变得一团糟。具体来说,只有常规文本(最初正常显示)的单元格被显示为链接(文本视图中的所有文本都是蓝色的,并且是一个活动链接),并且链接指向某些其他表格视图单元格。例如,链接可能指向位于不同表格视图单元格中的网站,或者向位于不同表格视图单元格中的地址发送电子邮件。

似乎在重复使用表格视图单元格时,即使文本视图文本正在更新,链接也会以某种方式被保存。

这只发生在 iOS 7 中,而不是 iOS 6。它发生在模拟器和我的设备上。

代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *sectionKey = [self.orderedSectionKeys objectAtIndex:indexPath.section];
    NSDictionary *infoDictionary = [[self.tableViewData objectForKey:sectionKey] objectAtIndex:indexPath.row];

    static NSString *cellIdentifier = @"InfoDefaultTableViewCell";
    InfoDefaultTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {        
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"InfoTableViewCells" owner:self options:nil];
        cell = [topLevelObjects objectAtIndex:0];
    }

    cell.bodyTextView.text = [infoDictionary objectForKey:@"description"];

    return cell;
}

有谁知道这里发生了什么,以及如何解决它?


我尝试在设置文本视图文本后添加此代码,以尝试重置链接:

cell.bodyTextView.dataDetectorTypes = UIDataDetectorTypeNone;
cell.bodyTextView.dataDetectorTypes = UIDataDetectorTypeAddress | UIDataDetectorTypeLink | UIDataDetectorTypePhoneNumber;

但这并没有改变我看到的行为。

【问题讨论】:

  • 尝试打印出保存到bodyTextView 中的文本:它将帮助您显示UITableViewCell 是否正在缓存其呈现的内容,或者正在检索的字符串是否不是您所期望的。跨度>
  • 设置好bodyTextView的文本后就可以记录了。它记录了我的期望(我设置的文本)。
  • 有趣。当您在 UI 中显示错误字符串的单元格上调用 setNeedsDisplay 时会发生什么? (您可以在调试器中执行此操作,以便于尝试。)
  • 正确的字符串显示在所有表格视图单元格中。问题是普通字符串显示为链接。例如,我可以有这样的文字:“这是我的文字。”并且它将是蓝色字体颜色并链接到,例如,在另一个表格视图单元格的文本视图中编写的网站。
  • 明白了。我刚刚在另一个相关主题上找到了这个答案,这听起来有帮助吗? stackoverflow.com/a/18968687/774

标签: ios uitableview uitextview ios7


【解决方案1】:

这似乎是 iOS 7.0 的 UITextViews 中的一个错误。 similar question 有一个似乎有帮助的解决方法:将文本视图的文本设置为 nil,然后再将其设置为新的文本字符串。

【讨论】:

  • 是的,提交错误。
  • 似乎是一个错误,但是将 text 设置为 nil,并没有为我做 :(
  • @BioCho 在哪个 iOS 版本上?
  • @BioCho 听起来 Theragon 的回答可能会有所帮助 (stackoverflow.com/a/19589680/774)
  • 我仍然在 iOS 8 中看到这个错误。啊。
【解决方案2】:

这里和通过提供的链接提供的一些建议并没有帮助我解决这个错误。

我尝试设置属性文本,将文本设置为零,将文本设置为@""。

最后,强制文本视图处于可编辑模式之外就可以了。准备重用

- (void)prepareForReuse
{
  ...
    textView.editable = YES;
    textView.editable = NO;
  ...
}

【讨论】:

  • 这行得通。发现这是重置 textColor 而不是不正确地添加链接,因此也必须重置 textColor。不幸的是,Instruments 告诉我,所有这些步骤结合起来甚至比在 iPod Touch iOS 7.1 上使用 setAttributedText: 还要慢。
  • 这对我有用,但只有当我在更新 text 属性之前也将属性文本设置为 nil 时。
【解决方案3】:

这些答案都不适合我(iOS8,Swift),唯一对我有用的是首先将文本设置为nil,然后在新文本前面加上一个不可见的空白 unicode 字符(我选择\u200B,这是 零宽度空间 字符,但任何字符都有效):

textView.text = nil
textView.text = "​\u{200B}\(newText)"

【讨论】:

  • 也适合我。惊人的!你有什么解释为什么它会这样工作吗?
  • 使用 Objective C 为我工作:textView.text = [@"\u200B" stringByAppendingString:message.content];
  • @melvinmt 你是怎么想出这个解决方案的,这让我很烦恼?这是最荒谬的解决方案,但它确实有效。
  • 不明白为什么它解决了这个问题,但它就像一个魅力。
【解决方案4】:

找到解决此问题的更好方法。每次设置文本时,这都需要一个额外的步骤。但这绝对可以解决问题。

_textView.selectable = NO; // set it to NO clears all possible data detection work so far.
_textView.selectable = YES; // set it to YES so that actual links are detected.

基本上数据检测需要将selectable 字段设置为YES 才能工作。当您将其设置为 NO 时,它会被完全删除。

注意:这仅适用于 ios7。

【讨论】:

  • 这可行,但会导致手势功能错误
【解决方案5】:

将文本设置为nil 在非常相似的问题中对我不起作用,但是 将scrollEnabled设置为NO,就像建议的here一样,对我有用。

编辑: 此外还有一个非常特殊的情况,它会导致问题:当一个盒子以链接开头并且新文本设置为空文本(@“” - 不是零!)时,盒子不知何故“坏了”,从那时起任何新文本变成了一个链接。我的解决方案是覆盖 setText 以首先将 [super text] 设置为 @"x",然后再设置为实际的新文本。将它设置为 nil 也没有解决这个问题。

【讨论】:

  • 如何设置【超文本】?
  • 我想通了,子类 UITextView,我还没有彻底测试过,但它似乎对我有用
【解决方案6】:

由于上述任何解决方案都对我有用,我发现的一种解决方法是在您应该更新每个单元格的文本而不是在可重复使用的单元格中重复使用时创建您的 UITextView

UITableViewCellDataSource 中的代码是:

- (void)updateDescriptionWithText:(NSString *)descriptionText
{
    UITextView *descriptionTV = [[UITextView alloc] initWithFrame:aFrame];
    [descriptionTV setScrollEnabled:NO]; 
    [descriptionTV setEditable:NO]; 
    [descriptionTV setDataDetectorTypes:UIDataDetectorTypeLink]; 
    if ([descriptionV respondsToSelector:@selector(setSelectable:)]) 
     [descriptionTV  setSelectable:YES];
    [descriptionTV setText:descriptionText];
    [self addSubview:descriptionTV];
}

而在UITableViewCell

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   ***your init code***

   [cell updateDescriptionWithText:description];
}   

【讨论】:

  • 您必须设法删除descriptionTV(如果您正在重用您的表格视图单元格,那么您应该重用您的表格视图单元格)。
【解决方案7】:

您可以使用 NSAttributedString 解决此问题。

cell.textview.attributedText = [[NSAttributedString alloc] initWithString:message.message];

【讨论】:

  • 这似乎是一个适当的修复。当您启用数据检测时,它们会从纯文本中获取单独的属性,因此整个文本变为 NSAttributedString。
【解决方案8】:

似乎在设置新文本之前将文本设置为nil 不起作用。您可能还需要能够滚动文本视图,因此设置 scrollEnabled 可能不是一个选项。

但是,当您创建一个属性字符串并将其设置到单元格的文本视图时,它会起作用。我使用了 collection view,但它应该与 table view 相同。我在collectionView:cellForItemAtIndexPath:中写了以下几行

//get the color and other properties from your UITextView
UIColor *textColor = cell.textView.textColor;
UIFont *messageFont = cell.textView.font;

//create your attributed string
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:yourStringForTheTextView attributes:@{NSForegroundColorAttributeName:textColor, NSFontAttributeName:messageFont}];

//set it to your UITextView
cell.textView.attributedText = attributedString;

希望这会有所帮助:)。

【讨论】:

  • 这是唯一可行的解​​决方案(除了涉及每次创建新 UITextView 的解决方案,出于性能原因我不想这样做)
  • 这会导致文本出现奇怪的闪烁
【解决方案9】:

建议的解决方法都不适合我。所以我决定创建一个新的 UITextView 并用旧的替换它,每次重用单元格时。它在性能方面并不理想,但至少它可以工作。

【讨论】:

    【解决方案10】:

    这个对我来说很可靠:

    // fix url detection bug
    cell.textView.dataDetectorTypes = UIDataDetectorTypeNone;
    cell.textView.dataDetectorTypes = UIDataDetectorTypeLink;
    

    【讨论】:

      【解决方案11】:

      将 Tint 颜色更改为其他颜色确实有效。 但是,如果可选择启用,则色调也将是相同的颜色。

      【讨论】:

        【解决方案12】:

        我也遇到了这个问题,我发现解决这个问题的方法是按以下顺序设置 textview 属性,

        [textview setDataDetectorTypes:UIDataDetectorTypeNone ];
        textView.editable = NO;
        [textView setDataDetectorTypes:UIDataDetectorTypeLink];
        textView.text=@"The text you need to show with link";
        

        希望对你有所帮助.....

        【讨论】:

          【解决方案13】:
          textView.text = nil;
          textView.attributedText = nil;
          
          textView.attributedText = [[NSAttributedString alloc] initWithString:@"your new string"];
          

          【讨论】:

            猜你喜欢
            • 2013-11-24
            • 2013-09-28
            • 1970-01-01
            • 2014-02-23
            • 2013-10-29
            • 2013-09-29
            • 1970-01-01
            • 2016-07-07
            • 2014-06-28
            相关资源
            最近更新 更多