web-dev-qa-db-ja.com

iOS 7のUITableViewリンク検出バグのUITextViews

UITextViewを含むカスタムUITableViewCellsがあります。 Interface BuilderでUITextViewのリンク検出をオンにしました。最初にテーブルビューを読み込むと、すべてが機能しているように見えますが、テーブルビューを上下にスクロールすると、リンクの検出が台無しになります。具体的には、通常は最初に表示されるテキストだけのセルがリンクとして表示され(テキストビュー内のすべてのテキストは青色になり、アクティブなリンクになります)、リンクは他のテーブルビューセル。たとえば、リンクは別のテーブルビューセルにあるWebサイトを指しているか、別のテーブルビューセルにあるアドレスにメールを送信します。

テキストビューのテキストが更新されていても、テーブルビューのセルが再利用されているときに、リンクが何らかの形で保存されているようです。

これはiOS 6ではなくiOS 7でのみ発生します。シミュレーターおよびデバイスで発生します。

コードは次のとおりです。

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

しかし、それは私が見ている振る舞いを変えませんでした。

46
Darren

これはiOS 7.0のUITextViewsのバグのようです。 同様の質問 に役立つ回避策があります。新しいテキスト文字列に設定する前に、テキストビューのテキストをnilに設定してください。

37
cbowns

ここでのいくつかの提案と提供されたリンクを介してこのバグを解決できませんでした。

属性付きテキストを設定し、テキストをnilに設定し、テキストを@ ""に設定してみました。

最終的には、テキストビューを強制的に編集可能モードから外すと、トリックが実行されました。再利用の準備中

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

これらの答えはどれも私にとってはうまくいきませんでした(iOS8、Swift)、私のために働いた唯一のことは、最初にテキストをnilに設定し、次に新しいテキストに非可視の空白Unicode文字を追加することでした(私は選択しました\u200B、これはZERO WIDTH SPACE文字ですが、どの文字でも機能します):

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

この問題を解決するより良い方法を見つけました。これには、テキストを設定するたびに追加の手順が必要です。しかし、これは間違いなく問題を解決します。

_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専用です。

6
Legolas

テキストをnilに設定しても同様の問題が発生しましたが、scrollEnabledをNOに設定すると、提案された here のようにうまくいきました。

編集:さらに、非常に特殊なケースがあり、それが問題を引き起こしました:ボックスがリンクで始まり、新しいテキストが空のテキスト(@ ""-nil!ではない)に設定されたとき、ボックスはどういうわけか "壊れました"新しいテキストではリンクになりました。私の解決策は、最初に[スーパーテキスト]を@ "x"に設定してから実際の新しいテキストに設定するようにsetTextをオーバーライドすることでした。代わりにnilに設定しても、この問題は解決しませんでした。

5
Tharagon

上記のソリューションのいずれかが私のために働いたので、私が見つけた回避策は、再利用可能なセルで再利用する代わりに各セルのテキストを更新することになっているときに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];
}   
3
Jason LAPIERRE

新しいテキストを設定する前にテキストをnilに設定しても機能しないようです。また、テキストビューをスクロールできる必要があるため、scrollEnabledを設定することはオプションではない場合があります。

ただし、セルのテキストビューに属性文字列を作成して設定すると機能します。 collection viewを使用しましたが、table viewsと同じでなければなりません。 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;

お役に立てれば :)。

2
Cornel

NSAttributedStringを使用して、この問題を修正できます。

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

推奨される回避策はどれも私にとってはうまくいきません。そこで、セルが再利用されるたびに、新しいUITextViewを作成して古いUITextViewに置き換えることにしました。パフォーマンスには理想的ではありませんが、少なくとも機能します。

1
tbergmen

これは私にとって確実に機能します:

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

色合いの色を他の色に変更すると、実際に機能します。ただし、選択可能な場合、色合いも同じ色になります。

0
Desmond

私もこの問題に直面しており、これを解決するために、textviewプロパティを次の順序で設定することがわかりました。

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

これがあなたを助けることを願っています.....

0