web-dev-qa-db-fra.com

UITextViews dans un bogue de détection de lien UITableView dans iOS 7

J'ai personnalisé UITableViewCells qui contiennent un UITextView. La détection de lien dans UITextView est activée dans Interface Builder. Lorsque je charge pour la première fois la vue tabulaire, tout semble fonctionner, mais lorsque je fais défiler la vue tabulaire, la détection des liens est perturbée. En particulier, les cellules ne contenant que du texte normal (qui sont normalement présentées au départ) sont affichées sous forme de liens (tout le texte de la vue Texte est coloré en bleu et constitue un lien actif), et les liens pointent vers des objets autres cellules de vue de tableau. Par exemple, un lien peut pointer vers un site Web se trouvant dans une cellule de vue tableau différente ou lancer un courrier électronique vers une adresse figurant dans une cellule de vue tableau différente.

Il semble que lorsque les cellules de la vue tableau sont réutilisées, même si le texte de la vue texte est mis à jour, les liens sont en quelque sorte sauvegardés.

Cela ne se produit que dans iOS 7, pas dans iOS 6. Cela se produit dans le simulateur et sur mon appareil.

Voici le 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;
}

Est-ce que quelqu'un sait ce qui se passe ici et comment le résoudre?


J'ai essayé d'ajouter ce code après avoir défini le texte en texte, pour essayer de réinitialiser les liens:

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

mais cela n'a pas changé le comportement que je vois.

46
Darren

Cela semble être un bogue dans UITextViews d'iOS 7.0. Une question similaire a une solution de contournement qui semble aider: définissez le texte de la vue texte sur nil avant de le définir sur la nouvelle chaîne de texte.

38
cbowns

Plusieurs suggestions ici et par les liens fournis ne m'ont pas aidé avec ce bug.

J'ai essayé de définir le texte attribué, de définir le texte sur nil, de définir le texte sur @ "".

En fin de compte, forcer la vue du texte dans un mode hors modifiable a fait l'affaire. En préparation pour la réutilisation

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

Aucune de ces réponses n’a fonctionné pour moi (iOS8, Swift), la seule chose qui a fonctionné pour moi a été d’abord de définir le texte sur nil, puis d’ajouter le nouveau texte avec un caractère unicode non visible (nous avons choisi \u200B, qui est le ZERO WIDTH SPACE caractère mais tout caractère fonctionne):

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

Trouver un meilleur moyen de résoudre ce problème. Cela nécessite une étape supplémentaire chaque fois que vous définissez du texte. Mais cela résout définitivement le problème. 

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

Fondamentalement, la détection de données nécessite que le champ selectable soit défini sur YES pour fonctionner. Lorsque vous le définissez sur NO, il est complètement supprimé.

Remarque: Ceci est uniquement pour ios7. 

6
Legolas

Définir le texte sur nil ne fonctionnait pas pour moi dans un problème très similaire, mais Régler scrollEnabled sur NO, comme suggéré ici , a fait l'affaire pour moi.

Edit: .__ De plus, il y avait toujours un cas très spécial qui posait problème: quand une boîte commençait par un lien et que le nouveau texte était réglé sur texte vide (@ "" - pas nil!), La boîte était "cassée" et à partir de là, tout nouveau texte devient un lien. Ma solution a été de remplacer setText pour définir d'abord [super texte] sur @ "x", puis sur le nouveau texte. Le mettre à zéro au lieu de cela n'a pas résolu ce problème non plus.

5
Tharagon

Comme l'une des solutions ci-dessus a fonctionné pour moi, la solution que j'ai trouvée consiste à créer votre UITextView lorsque vous êtes censé mettre à jour le texte de chaque cellule au lieu de le réutiliser dans la cellule réutilisable.

Votre code dans la UITableViewCellDataSource serait:

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

Et dans la UITableViewCell:

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

   [cell updateDescriptionWithText:description];
}   
3
Jason LAPIERRE

Il semble que définir le texte sur nil avant de définir le nouveau texte ne fonctionne pas. Vous devrez peut-être également être en mesure de faire défiler la vue de texte. Par conséquent, définir scrollEnabled pourrait ne pas être une option.

Toutefois, cela fonctionne lorsque vous créez et définissez une chaîne attribuée dans la vue texte de la cellule. J'ai utilisé une vue collection, mais il devrait en être de même avec la vue table. J'ai écrit les lignes suivantes dans le 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;

J'espère que cela t'aides :).

2
Cornel

Vous pouvez résoudre ce problème en utilisant NSAttributedString.

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

Aucune des solutions de contournement suggérées ne fonctionne pour moi. J'ai donc décidé de créer un nouveau UITextView et de le remplacer par l'ancien, chaque fois que la cellule est réutilisée. Ce n'est pas idéal pour la performance, mais au moins ça marche.

1
tbergmen

Celui-ci fonctionne de manière fiable pour moi:

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

Le fait de changer la couleur de teinte en une autre couleur fonctionne réellement ..__ Cependant, si vous sélectionnez Activer, la teinte sera également de la même couleur.

0
Desmond

Je suis également confronté à ce problème et j’ai découvert que le résoudre consistait à définir les propriétés textview dans l’ordre suivant,

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

J'espère que cela vous aidera .....

0
Paulson Varghese