简体   繁体   English

UITextViews在iOS 7中的UITableView链接检测错误中

[英]UITextViews in a UITableView link detection bug in iOS 7

I have custom UITableViewCells that contain a UITextView. 我有自定义UITableViewCells包含UITextView。 I have link detection in the UITextView turned on in Interface Builder. 我在Interface Builder中打开了UITextView中的链接检测。 When I first load the table view, everything seems to be working, but as I scroll up and down the table view, the link detection gets messed up. 当我第一次加载表视图时,一切似乎都在工作,但是当我在表视图中向上和向下滚动时,链接检测会搞砸。 Specifically, cells that just have regular text (which are presented normally initially) are being shown as links (all the text in the text view is coloured blue and is an active link), and the links point to objects that are in some of the other table view cells. 具体来说,只有常规文本(通常最初显示)的单元格显示为链接(文本视图中的所有文本都显示为蓝色并且是活动链接),并且链接指向某些文本中的对象。其他表视图单元格。 For example a link might point to a website that was in a different table view cell, or launch an email to an address that was in a different table view cell. 例如,链接可能指向位于不同表视图单元格中的网站,或者将电子邮件发送到位于不同表格视图单元格中的地址。

It seems like when the table view cells are being reused, even though the text view text is being updated, the links are somehow getting saved. 看起来当表视图单元格被重用时,即使正在更新文本视图文本,链接也会以某种方式被保存。

This only happens in iOS 7, not iOS 6. It happens in the simulator and on my device. 这只发生在iOS 7,而不是iOS 6.它发生在模拟器和我的设备上。

Here is the code: 这是代码:

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

Does anyone know what is happening here, and how to solve it? 有谁知道这里发生了什么,以及如何解决它?


I tried adding this code after setting the text view text, to try to reset the links: 我尝试在设置文本视图文本后添加此代码,尝试重置链接:

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

but it didn't change the behaviour that I'm seeing. 但它并没有改变我所看到的行为。

This appears to be a bug in iOS 7.0's UITextView s. 这似乎是iOS 7.0的UITextView的一个错误。 A similar question has a workaround which seems to help: set the text view's text to nil before setting it to the new text string. 类似的问题有一个似乎有用的解决方法:在将文本视图的文本设置为新文本字符串之前将其设置为nil

Several suggestions here and through links provided did not help me with this bug. 这里提供的一些建议和通过提供的链接并没有帮助我解决这个问题。

I tried setting attributed text, setting text to nil, setting text to @"". 我尝试设置属性文本,将文本设置为nil,将文本设置为@“”。

In the end forcing the text view in an out of editable mode did the trick. 最后,在一个不可编辑的模式下强制文本视图就可以了。 In prepare for reuse 准备重用

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

None of these answers worked for me (iOS8, Swift), the only thing that worked for me was to first set the text to nil and then prepend the new text with a non-visibile whitespace unicode character (I chose \​ , which is the ZERO WIDTH SPACE character but any character works): 这些答案都不适用于我(iOS8,Swift),对我来说唯一有用的是首先将文本设置为nil然后在前面添加一个非visibile空格unicode字符(我选择\​ ,这是ZERO WIDTH SPACE字符,但任何角色都有效):

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

Found a better way to solve this problem. 找到了解决这个问题的更好方法。 This requires an extra step every single time you set text. 每次设置文本时都需要额外的步骤。 But this definitely fixes the problem. 但这肯定解决了这个问题。

_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.

Basically data detection requires the selectable field to be set to YES to work. 基本上,数据检测要求将selectable字段设置为YES才能工作。 When you set it to NO, its completely removed. 当您将其设置为NO时,将其完全删除。

Note: This is only for ios7. 注意:这仅适用于ios7。

Setting the text to nil did not work for me in a very similar problem, but setting scrollEnabled to NO , like suggested here , did the trick for me. 将文本设置为nil对我来说在一个非常类似的问题中不起作用,但是将scrollEnabled设置为NO ,就像这里建议的那样,对我来说是个窍门。

Edit: In addition there was still a very special case, that caused problems: When a box began with a link and the new text was set to empty text (@"" - not nil!) the box somehow "broke" and from then on any new text became a link. 编辑:此外还有一个非常特殊的情况,导致问题:当一个框开始一个链接并且新文本被设置为空文本(@“” - 不是零!)时,该框以某种方式“破坏”并从那时开始在任何新文本成为一个链接。 My solution was to override setText to set [super text] to @"x" first and then to the actual new text. 我的解决方案是覆盖setText,先将[super text]设置为@“x”,然后再设置为实际的新文本。 Setting it to nil instead did not solve this problem either. 将其设置为nil也没有解决这个问题。

As any of the above solutions worked for me, a workaround I've found is to create your UITextView when you are supposed to update the text for each cell instead of reusing in the reusable cell. 由于上述任何解决方案都适用于我,我发现一种解决方法是在您应该更新每个单元格的文本而不是在可重用单元格中重用时创建UITextView

Your code in the UITableViewCellDataSource would be : 您在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];
}

And in the UITableViewCell : UITableViewCell

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

   [cell updateDescriptionWithText:description];
}   

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

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

It seems that setting the text to nil before setting the new text doesn't work. 似乎在设置新文本之前将文本设置为nil不起作用。 You also might need to be able to scroll the text view, so setting the scrollEnabled might not be an option. 您可能还需要能够滚动文本视图,因此设置scrollEnabled可能不是一个选项。

However, it works when you create and set an attributed string to the cell's text view. 但是,当您在单元格的文本视图中创建和设置属性字符串时,它可以正常工作。 I used a collection view , but it should be the same with table views . 我使用了一个集合视图 ,但它应该与表视图相同。 I wrote the following lines in the collectionView:cellForItemAtIndexPath: 我在collectionView:cellForItemAtIndexPath:写了以下几行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;

Hope this helps :). 希望这可以帮助 :)。

Non of the suggested workarounds work for me. 没有建议的解决方法适合我。 So I decided to create a new UITextView and replace it with the old one, every time the cell is reused. 因此,每次重复使用单元格时,我决定创建一个新的UITextView并将其替换为旧的UITextView。 It is not ideal for performance, but at least it works. 它不是理想的性能,但至少它可以工作。

This one works reliably for me: 这个对我来说可靠:

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

Changing the Tint color to other color actually works. 将色调颜色更改为其他颜色实际上有效。 However if selectable enable the tint will also be the same color. 但是,如果可选择启用,则色调也将是相同的颜色。

I also face this problem and I found out to solve this is to set textview properties in the following order, 我也遇到了这个问题,我发现解决这个问题是按以下顺序设置textview属性,

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

Hope this help you..... 希望这能帮到你......

textView.text = nil;
textView.attributedText = nil;

textView.attributedText = [[NSAttributedString alloc] initWithString:@"your new string"];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM