J'ai un UITableview
avec plusieurs TableViewCells réutilisables. Dans une cellule, j'ai une UITextView
, qui se redimensionne pour s'adapter à son contenu. Maintenant, je "juste" dois redimensionner la contentView
de la TableViewCell, afin que je puisse lire le texte while. J'ai déjà essayé:
cell2.contentView.bounds.size.height = cell2.discriptionTextView.bounds.size.height;
Ou:
cell2.contentView.frame = CGRectMake(0, cell2.discriptionTextView.bounds.Origin.y,
cell2.discriptionTextView.bounds.size.width,
cell2.discriptionTextView.bounds.size.height);
Dans la méthode:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath {}
Mais ça ne marchera pas.
Est-ce que quelqu'un sait comment faire ça?
Nouveau code:
@implementation AppDetail
CGFloat height;
…
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{…
cell2.TextView.text = self.text;
[cell2.TextView sizeToFit];
height = CGRectGetHeight(cell2.TextView.bounds);
…
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
return 143;
}
if (indexPath.row == 1) {
return height;
}
return 0;
}
Vous devez implémenter heightForRowAtIndexPath
.
Supposons que les données à afficher dans textView soient stockées dans un NSArray.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat cellheight = 30; //assuming that your TextView's Origin.y is 30 and TextView is the last UI element in your cell
NSString *text = (NSString *)[textArray objectAtIndex:indexpath.row];
UIFont *font = [UIFont systemFontOfSize:14];// The font should be the same as that of your textView
CGSize constraintSize = CGSizeMake(maxWidth, CGFLOAT_MAX);// maxWidth = max width for the textView
CGSize size = [text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
cellHeight += size.height; //you can also add a cell padding if you want some space below textView
}
Vous pouvez uniquement redimensionner un UITableViewCell dans la méthode déléguée tableView:heightForRowAtIndexPath:
.
Vous devez estimer quelle sera la taille du texte lorsque cette méthode sera appelée pour chaque ligne lors du chargement de la tableView.
C'est ce que j'ai fait pour résoudre le problème.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * yourText = self.myArrayWithTextInIt[indexPath.row]; // or however you are getting the text
return additionalSpaceNeeded + [self heightForText:yourText];
}
-(CGFloat)heightForText:(NSString *)text
{
NSInteger MAX_HEIGHT = 2000;
UITextView * textView = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, WIDTH_OF_TEXTVIEW, MAX_HEIGHT)];
textView.text = text;
textView.font = // your font
[textView sizeToFit];
return textView.frame.size.height;
}
MODIFIER
Bien que j'ai utilisé cette solution pendant un certain temps, j'ai trouvé une solution plus optimale que je vous recommanderais, car elle ne nécessite pas l'allocation d'un textView complet pour fonctionner et peut gérer un texte supérieur à 2000.
-(CGFloat)heightForTextViewRectWithWidth:(CGFloat)width andText:(NSString *)text
{
UIFont * font = [UIFont systemFontOfSize:12.0f];
// this returns us the size of the text for a rect but assumes 0, 0 Origin
CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}];
// so we calculate the area
CGFloat area = size.height * size.width;
CGFloat buffer = whateverExtraBufferYouNeed.0f;
// and then return the new height which is the area divided by the width
// Basically area = h * w
// area / width = h
// for w we use the width of the actual text view
return floor(area/width) + buffer;
}
Comme @Rob Norback l'a dit, il existe quelque chose appelé UITableViewAutomaticDimension
.
Pour Swift, le moyen le plus simple de redimensionner le contenu de UITableViewCell à la volée consiste simplement à ajouter ceci.
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Voici une version mise à jour pour iOS 7+ qui est plus propre (pas de méthode supplémentaire)
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIFont * font = [UIFont systemFontOfSize:15.0f];
NSString *text = [getYourTextArray objectAtIndex:indexPath.row];
CGFloat height = [text boundingRectWithSize:CGSizeMake(self.tableView.frame.size.width, maxHeight) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName: font} context:nil].size.height;
return height + additionalHeightBuffer;
}
Je préfère cette solution de Jure
textView.scrollEnabled
Ensemble
table.rowHeight = UITableViewAutomaticDimension;
tableView.estimatedRowHeight = 44;
Si finalement, votre code ne fonctionne pas, utilisez plutôt ceci
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}
Implémentez UITextViewDelegate
comme ceci:
- (void)textViewDidChange:(UITextView *)textView {
CGPoint currentOffset = self.tableView.contentOffset;
[UIView setAnimationsEnabled:NO];
[self.tableView beginUpdates];
[self.tableView endUpdates];
[UIView setAnimationsEnabled:YES];
[self.tableView setContentOffset:currentOffset animated:NO];
}
Ce fil de discussion a pris pas mal de temps, mais dans iOS 8, UITableViewAutomaticDimension
a été introduit. Pour que cela fonctionne, vous devez définir des contraintes de haut en bas de la cellule, comme une vue en défilement. Mais après cela, ajoutez simplement le code suivant à viewDidLoad()
:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 122.0
Assurez-vous que votre hauteur estimée est aussi proche que possible de la réalité, sinon vous aurez du défilement buggé.
L'ajout de ces deux méthodes à ViewController avec UITableViewAutomaticDimension devrait faire l'affaire. Cela a fonctionné pour moi lors de l'intégration d'une UITextView dans une UITableViewCell avec un texte de longueur variable.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
Dans le cas d'une sous-vue UILabel dans UITableViewCell, j'ai effectué le redimensionnement automatique de l'étiquette en définissant simplement les contraintes de l'étiquette (à l'aide du storyboard, Xcode 8.3.2).
Cela fonctionne car apparemment le comportement par défaut de l'étiquette et de la cellule est sizeToFit. Même chose devrait fonctionner pour UITextView.