Je connais donc la raison de cette erreur, mais je ne sais pas vraiment comment la contourner.
J'ai un TextField
que je ne veux pas être modifiable, mais avec le défilement activé dans une vue.
Voici comment j'ai configuré cette vue:
- (void)tableView:(UITableView *) tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *component = self.resultsTuples[indexPath.row];
NSString* serverUrl = @"http://staging.toovia.com";
NSString* pageLink = component[@"$element"][@"ContactCard"][@"PageLink"];
NSString* recUrl =[NSString stringWithFormat:@"%@%@&format=json&fields=summary&fields=session_info", serverUrl,pageLink];
[AJAXUtils getAsyncJsonWithUrl:(NSURL *)[NSURL URLWithString:recUrl] callback:^(NSDictionary *returnjson){
if (returnjson != nil){
NSLog(@"RETURN JSON : %@", returnjson);
NSString *userPageLink = returnjson[@"Node"][@"SessionInfo"][@"PostingAs"][@"Key"];
self.detailController.userPageLink = userPageLink;
self.detailController.nodePage = returnjson[@"Node"][@"Key"];
NSString *selectedCard = component[@"$element"][@"Title"];
// [self.detailController setDescription:component[@"element"][@"ContactCard"][@"Description"]];
[self.detailController setPageTitle:selectedCard];
NSString* photoUrl = component[@"$element"][@"ContactCard"][@"Cover"][@"Medium"][@"Link"];
[self.detailController setRestaurantImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:photoUrl]]]];
self.detailController.title = selectedCard;
NSString* rating = component[@"$element"][@"Summary"][@"AverageRating"];
self.detailController.rating =(NSInteger)rating;
[self.navigationController pushViewController:self.detailController animated:YES];
}
}];
Voici le code viewWillAppear
pour la vue:
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear: animated];
self.rateView.notSelectedStar =[UIImage imageNamed:@"star-off.png"];
self.rateView.fullSelectedStar = [UIImage imageNamed:@"star-on.png"];
self.rateView.rating = self.rating;
self.rateView.editable = YES;
self.rateView.maxRating = 5;
self.rateView.delegate = self;
_pageTitleLabel.text = _pageTitle;
_pageScoreLabel.text = _pageScore;
_trendingImageView.image = [UIImage imageNamed:@"trending.png"];
_restaurantImageView.image = _restaurantImage;
}
L'erreur complète est -
2013-12-16 01:22:50.362 ReviewApp[7332:441f] *** Assertion failure in void _UIPerformResizeOfTextViewForTextContainer(NSLayoutManager *, UIView<NSTextContainerView> *, NSTextContainer *, NSUInteger)(), /SourceCache/UIFoundation_Sim/UIFoundation-258.1/UIFoundation/TextSystem/NSLayoutManager_Private.m:1510
2013-12-16 01:22:50.365 ReviewApp[7332:441f] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!'
Je suppose donc que cela se produit parce que le redimensionnement du champ de texte (lorsque le contenu est défini) doit se produire sur le thread principal. Comment puis-je forcer cela à se produire/supprimer cette erreur? Je ne contrôle pas le redimensionnement du champ de texte, n'est-ce pas?
Merci
Je suppose que le rappel de AJAXUtils
se produit sur un thread d'arrière-plan. Je ne sais pas si c'est votre code ou non, mais vous devriez faire toutes les opérations d'interface utilisateur (comme définir du texte dans une étiquette, définir une image dans une vue d'image, pousser un contrôleur de vue) sur le thread principal.
dispatch_sync(dispatch_get_main_queue(), ^{
/* Do UI work here */
});
Version Swift 3.0
DispatchQueue.main.async(execute: {
/* Do UI work here */
})
Vous devez toujours exécuter du code d'interface utilisateur sur le thread principal. Vous ne l'êtes pas, d'où l'erreur. Essaye ça:
[AJAXUtils getAsyncJsonWithUrl:(NSURL *)[NSURL URLWithString:recUrl] callback:^(NSDictionary *returnjson){
if (returnjson != nil){
NSLog(@"RETURN JSON : %@", returnjson);
NSString *userPageLink = returnjson[@"Node"][@"SessionInfo"][@"PostingAs"][@"Key"];
self.detailController.userPageLink = userPageLink;
self.detailController.nodePage = returnjson[@"Node"][@"Key"];
NSString *selectedCard = component[@"$element"][@"Title"];
// [self.detailController setDescription:component[@"element"][@"ContactCard"][@"Description"]];
[self.detailController setPageTitle:selectedCard];
NSString* photoUrl = component[@"$element"][@"ContactCard"][@"Cover"][@"Medium"][@"Link"];
[self.detailController setRestaurantImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:photoUrl]]]];
self.detailController.title = selectedCard;
NSString* rating = component[@"$element"][@"Summary"][@"AverageRating"];
self.detailController.rating =(NSInteger)rating;
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController pushViewController:self.detailController animated:YES];
});
}
}];
Cela garantit que l'affichage du contrôleur de vue est sur le thread principal. Vous devrez peut-être mettre un peu plus de code dans l'appel à dispatch_async
.
Version Swift
dispatch_async(dispatch_get_main_queue()){
/* Do UI work here */
}
De plus, ce n'est pas une très bonne façon de faire les choses dans didSelectRow. Vous devriez avoir une couche réseau, séparer le code réseau des contrôleurs de vue, sinon vous vous retrouverez avec un contrôleur de vue énorme, le code ne sera pas testable.