Je crée une vue comme iMessage, il suffit de saisir du texte dans la vue de texte inférieure. J'utilise la vue tabulaire pour ce faire, et la vue texte dans la dernière cellule. lorsque je saisis du texte long sur plusieurs lignes, j'ai besoin que la vue texte et la cellule deviennent plus personnalisées. j'ai donc besoin de rafraîchir la hauteur de la cellule. mais si j'utilise le rechargement de la vue tabulaire ou la ligne de rechargement, le contenu en mode texte disparaîtra et le clavier disparaîtra également. Y a-t-il un meilleur moyen de le réparer?
Peut-être devrais-je utiliser la barre d'outils pour le faire facilement? mais je doute toujours que la vue de table puisse le faire.
Les cellules seront redimensionnées en douceur lorsque vous appelez beginUpdates
et endUpdates
. Après ces appels, la tableView enverra tableView:heightForRowAtIndexPath:
pour toutes les cellules du tableau, lorsque tableView a obtenu toutes les hauteurs pour toutes les cellules, il animera le redimensionnement.
Et vous pouvez mettre à jour les cellules sans les recharger en définissant directement les propriétés de la cellule. Il n'est pas nécessaire d'impliquer la tableView et tableView:cellForRowAtIndexPath:
Pour redimensionner les cellules, vous utiliseriez un code similaire à celui-ci
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
NSString *newText = [textView.text stringByReplacingCharactersInRange:range withString:text];
CGSize size = // calculate size of new text
if ((NSInteger)size.height != (NSInteger)[self tableView:nil heightForRowAtIndexPath:nil]) {
// if new size is different to old size resize cells.
// since beginUpdate/endUpdates calls tableView:heightForRowAtIndexPath: for all cells in the table this should only be done when really necessary.
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
return YES;
}
pour changer le contenu d'une cellule sans recharger j'utilise quelque chose comme ceci:
- (void)configureCell:(FancyCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
MyFancyObject *object = ...
cell.textView.text = object.text;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FancyCell *cell = (FancyCell *)[tableView dequeueReusableCellWithIdentifier:@"CellWithTextView"];
[self configureCell:cell forRowAtIndexPath:indexPath];
return cell;
}
// whenever you want to change the cell content use something like this:
NSIndexPath *indexPath = ...
FancyCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self configureCell:cell forRowAtIndexPath:indexPath];
J'ai écrit une sous-classe de UITableViewCell pour gérer cette fonctionnalité.
Fichier .h:
#import <UIKit/UIKit.h>
@protocol AECELLSizeableDelegate;
@interface AECELLSizeable : UITableViewCell
@property (weak, nonatomic) id <AECELLSizeableDelegate> delegate;
@property IBOutlet UIView *viewMinimized;
@property IBOutlet UIView *viewMaximized;
@property BOOL maximized;
@property CGFloat height;
- (IBAction)clickedConfirm:(id)sender;
- (IBAction)clickedCancel:(id)sender;
- (void)minimizeForTableview: (UITableView*)tableView;
- (void)maximizeForTableview: (UITableView*)tableView;
- (void)toggleForTableview: (UITableView*)tableView;
@end
@protocol AECELLSizeableDelegate <NSObject>
- (void)sizeableCellConfirmedForCell: (AECELLSizeable*)cell;
- (void)sizeableCellCancelledForCell: (AECELLSizeable*)cell;
@end
Fichier .m:
#import "AECELLSizeable.h"
@implementation AECELLSizeable
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)minimizeForTableview: (UITableView*)tableView
{
self.maximized = NO;
[self.viewMinimized setHidden:NO];
[self.viewMaximized setHidden:YES];
self.height = self.viewMinimized.frame.size.height;
[tableView beginUpdates];
[tableView endUpdates];
}
- (void)maximizeForTableview: (UITableView*)tableView
{
self.maximized = YES;
[self.viewMinimized setHidden:YES];
[self.viewMaximized setHidden:NO];
self.height = self.viewMaximized.frame.size.height;
[tableView beginUpdates];
[tableView endUpdates];
}
- (void)toggleForTableview:(UITableView *)tableView
{
if (self.maximized) {
[self minimizeForTableview:tableView];
} else {
[self maximizeForTableview:tableView];
}
}
- (void)clickedConfirm:(id)sender
{
[self.delegate sizeableCellConfirmedForCell:self];
}
- (void)clickedCancel:(id)sender
{
[self.delegate sizeableCellCancelledForCell:self];
}
@end
Exemple d'utilisation:
Définissez la méthode de rappel heightForRowAtIndexPath de tableview dans le fichier d'implémentation du contrôleur tableview en tant que telle:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
//Sizeable Cell
return self.cellSizeable.height;
} else {
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
Dans la méthode viewDidLoad de votre contrôleur tableview, appelez minimForTableview sur votre cellule pour vous assurer qu'elle démarre au minimum.