J'ai implémenté TableView avec CustomCell dans mon application,
Je veux la hauteur dynamique de mon UITableViewCell
en fonction de la longueur du texte dans UITableViewCell
,
voici l'instantané de Customcell
: et voici l'instantané de mon UITableView
: extrait de code pour heightForRowAtIndexPath
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 10.0f
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSString *text = [DescArr objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 100.0);
return height;
}
Comme vous pouvez le voir sur la 2e image, la hauteur de la cellule est fixe, elle ne change pas avec sa taille de texte (contenu).
Où est-ce que je me trompe? Comment puis-je créer une étiquette ou une cellule pour mettre à jour sa taille en fonction de son contenu/texte?
Le code suivant a bien fonctionné pour moi.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat lRetval = 10;
CGSize maximumLabelSize = CGSizeMake(231, FLT_MAX);
CGSize expectedLabelSize;
CGFloat numberoflines = [thirdcellText length]/17.0;
if (indexPath.section == 0) {
expectedLabelSize = [firstcellText sizeWithFont:[UIFont systemFontOfSize:16.0]
constrainedToSize:maximumLabelSize
lineBreakMode:NSLineBreakByWordWrapping];
lRetval = expectedLabelSize.height;
}
else if(indexPath.section == 1)
{
expectedLabelSize = [secondcellText sizeWithFont:[UIFont systemFontOfSize:16.0]
constrainedToSize:maximumLabelSize
lineBreakMode:NSLineBreakByWordWrapping];
lRetval = expectedLabelSize.height;
}
else if (indexPath.section == 2)
{
expectedLabelSize = [thirdcellText sizeWithFont:[UIFont systemFontOfSize:16.0]
constrainedToSize:CGSizeMake(231, numberoflines*17.0)
lineBreakMode:NSLineBreakByWordWrapping];
lRetval = expectedLabelSize.height-128.0;
}
UIImage *factoryImage = [UIImage imageNamed:NSLocalizedString(@"barcode_factory_reset.png", @"")];
CGFloat height = factoryImage.size.height;
if (lRetval < height) {
lRetval = height+15.0;
}
return lRetval;
}
Essayez d'ajouter le code suivant dans votre méthode de mise en page automatique de classe de cellule personnalisée
textview.frame = frame;
CGRect frame1 = textview.frame;
frame1.size.height = textview.contentSize.height-2;
textview.frame = frame1;
textview.contentSize = CGSizeMake(textview.frame.size.width, textview.frame.size.height);
labelPtr.frame = CGRectMake(CGRectGetMinX(imageView.frame)+CGRectGetMaxX(imageView.frame)+5.0, textview.frame.size.height+10.0, 140, 16.0);
[labelPtr setNeedsDisplayInRect:labelPtr.frame];
Essayez de définir les propriétés de l'étiquette comme suit
labelPtr = [[UILabel alloc] initWithFrame:CGRectZero];
labelPtr.backgroundColor =[UIColor clearColor];
[labelPtr setNeedsLayout];
[labelPtr setNeedsDisplay];
[self.contentView addSubview:labelPtr];
S'il vous plaît, regardez ICI - Tutoriel sur la hauteur dynamique des cellules et la disposition automatique de la table.
De quoi as-tu besoin:
Méthodes:
//this will calculate required height for your cell
-(CGFloat)heightForBasicCellAtIndexPath:(NSIndexPath *)indexPath {
static UIYourClassCellName *sizingCell = nil;
//create just once per programm launching
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:@"identifierOfCell"];
});
[self configureBasicCell:sizingCell atIndexPath:indexPath];
return [self calculateHeightForConfiguredSizingCell:sizingCell];
}
//this method will calculate required height of cell
- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell {
[sizingCell setNeedsLayout];
[sizingCell layoutIfNeeded];
CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height;
}
Et appeler
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self heightForBasicCellAtIndexPath:indexPath];
}
Configuration de la cellule
- (void)configureBasicCell:(RWBasicCell *)cell atIndexPath:(NSIndexPath *)indexPath {
//make some configuration for your cell
}
Après toute opération, je suis passé (texte à l'intérieur de la cellule uniquement comme espace réservé):
Je cherche depuis longtemps à déterminer correctement la hauteur des cellules, - semble - c'est une meilleure solution, boundingRectWithSize et constrainedToSize souvent la hauteur de texte incorrectement calculée, vous devez créer UILabel que d'utiliser la fonction sizeThatFits, voir ci-dessous
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(8, 5, celllabelWidth, 9999)];
label.numberOfLines=0;
label.font = [UIFont fontWithName:fontName size:textSize];
label.text = @"celllabelTextHere";
CGSize maximumLabelSize = CGSizeMake(celllabelWidth, 9999);
CGSize expectedSize = [label sizeThatFits:maximumLabelSize];
return expectedSize.height;
}
C'est très simple maintenant
Utilisez les étapes ci-dessous
self.tableView.estimatedRowHeight = 100.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
Prendre plaisir:)
Pour plus de détails, vous pouvez vérifier
www.raywenderlich.com
stackoverflow.com
J'ai vu beaucoup de solutions mais tout était faux ou incomplet. Vous pouvez résoudre tous les problèmes avec 5 lignes dans viewDidLoad et autolayout. Ceci pour l'objectif C:
_tableView.delegate = self;
_tableView.dataSource = self;
self.tableView.estimatedRowHeight = 80;//the estimatedRowHeight but if is more this autoincremented with autolayout
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) ;
Pour Swift 2.0:
self.tableView.estimatedRowHeight = 80
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.setNeedsLayout()
self.tableView.layoutIfNeeded()
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)
Maintenant, créez votre cellule avec xib ou dans tableview dans votre Storyboard Avec cela, vous n'avez plus besoin de rien implémenter ou de remplacer. (N'oubliez pas le numéro des lignes 0) et le bas de l'étiquette (contraindre) rétrograder "Priorité à l'étirement du contenu - Vertical à 250"
Vous pouvez télécharger le code dans l'url suivante: https://github.com/jposes22/exampleTableCellCustomHeight
Références: http://candycode.io/automatically-resizing-uitableviewcells-with-dynamic-text-height-using-auto-layout/
Pourriez-vous essayer ceci;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
int topPadding = cell.yourLabel.frame.Origin.x;
int bottomPadding = cell.frame.size.heigth-(topPadding+cell.yourLabel.frame.size.height);
NSString *text = [DescArr objectAtIndex:[indexPath row]];
CGSize maximumSize = CGSizeMake(cell.yourLabel.frame.size.width, 9999);
CGSize expectedSize = [text sizeWithFont:yourCell.yourLabel.font constrainedToSize:maximumSize lineBreakMode:yourCell.yourLabel.lineBreakMode];
return topPadding+expectedSize.height+bottomPadding;
}
Référez-vous à ce lien que vous utilisez Autolayout
sinon vous pouvez utiliser l'approche ci-dessous
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NewsVCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
if (cell == nil)
{
cell = [[NewsVCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
cell.titleCell.numberOfLines = 0;
cell.descriptionCell.numberOfLines = 0;
cell.titleCell.font = [UIFont systemFontOfSize:12.0f];
cell.descriptionCell.font = [UIFont systemFontOfSize:12.0f];
cell.descriptionCell.textColor = [UIColor lightGrayColor];
CGSize maximumLabelSize;
if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"])
{
maximumLabelSize = CGSizeMake(768, 10000);
}
else
{
maximumLabelSize = CGSizeMake(270, 10000);
}
NSString *newsTitle = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
NSString *descriptionsText = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
CGSize expectedTitleLabelSize = [newsTitle sizeWithFont: cell.titleCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.titleCell.lineBreakMode];
CGSize expectedDescriptionLabelSize = [descriptionsText sizeWithFont:cell.descriptionCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.descriptionCell.lineBreakMode];
NSLog(@"cellForRowAtIndexPath :indexpath.row %d: height expectedTitleLabelSize:%f , indexpath.row height expectedDescriptionLabelSize:%f",indexPath.row,expectedTitleLabelSize.height,expectedDescriptionLabelSize.height);
if (newsTitle.length > 0)
{
cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height+20.0f);
}
else
{
cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height-20.0f);
}
if (descriptionText.length > 0)
{
cell.descriptionCell.frame = CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f);
}
else
{
cell.descriptionCell.frame = CGRectMake(20.0f, cell.titleCell.frame.size.height, 270.0f, 0.0f);
}
cell.descriptionCell.frame = CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f);
cell.titleCell.text = newsTitle;
cell.descriptionCell.text = descriptionsText;
NSLog(@"indexpath.row %d :title %@ ",indexPath.row,newsTitle);
NSLog(@"indexpath.row %d :description %@",indexPath.row,descriptionsText);
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
float totalHeight = 0.0f;
UILabel *labelTitle;
CGSize maximumLabelSize;
if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"])
{
labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 692.0f, 20.0f)]; // iPad
maximumLabelSize = CGSizeMake(768.0f, 10000.0f);
}
else
{
labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 270.0f, 20.0f)];
maximumLabelSize = CGSizeMake(270.0f, 10000.0f);
}
labelTitle.font = [UIFont systemFontOfSize:12.0f];
NSString *newsTitle;
NSString *newsDescription;
// cell.titleCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
// cell.descriptionCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
newsTitle = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
newsDescription = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
NSLog(@"indexpath.row %d :newsDescription.length %d",indexPath.row,newsDescription.length);
CGSize expectedTitleLabelSize;
CGSize expectedDescriptionLabelSize;
if (newsTitle.length > 0)
{
expectedTitleLabelSize = [newsTitle sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode];
totalHeight = totalHeight + 20.0f;
}
else
{
expectedTitleLabelSize = CGSizeMake(0.0f, 0.0f);
totalHeight = -20.0f;
}
if (newsDescription.length > 0)
{
expectedDescriptionLabelSize = [newsDescription sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode];
totalHeight = totalHeight + 20.0f;
}
else
{
expectedDescriptionLabelSize = CGSizeMake(0.0f, 0.0f);
totalHeight = -20.0f;
}
// NSLog(@"question: %f title:%f",expectedQuestionLabelSize.height,expectedTitleLabelSize.height);
totalHeight = expectedDescriptionLabelSize.height + expectedTitleLabelSize.height + 30.0f+20.0f;
return totalHeight;
}
Si vous souhaitez limiter la hauteur maximale à 100 pt, vous devez utiliser MIN
à la place sur MAX
:
CGFloat height = fmin(size.height, 100.0);
Pour définir la dimension automatique pour la hauteur de ligne et la hauteur de ligne estimée, assurez-vous que les étapes suivantes sont effectives, la dimension automatique est efficace pour la disposition de hauteur de cellule/ligne.
UITableViewAutomaticDimension
à rowHeight & estimeRowHeightheightForRowAt
et renvoyez-lui une valeur UITableViewAutomaticDimension
)-
@IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Don't forget to set dataSource and delegate for table
table.dataSource = self
table.delegate = self
// Set automatic dimensions for row height
// Swift 4.2 onwards
table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = UITableView.automaticDimension
// Swift 4.1 and below
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Swift 4.2 onwards
return UITableView.automaticDimension
// Swift 4.1 and below
return UITableViewAutomaticDimension
}
Pour l'instance d'étiquette dans UITableviewCell
Essayez ceci, cela a fonctionné comme un charme! pour moi,
Dans viewDidLoad, écrivez ce code,
-(void)viewDidLoad
{
[super viewDidLoad];
self.tableView.estimatedRowHeight = 100.0; // for example. Set your average height
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
Dans cellForRowAtIndexPath écrivez ce code,
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.numberOfLines = 0; // Set label number of line to 0
cell.textLabel.text=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"menu"];
[cell.textLabel sizeToFit]; //set size to fit
return cell;
}
J'espère que cela aidera quelqu'un.
J'avais besoin d'une hauteur de cellule de vue de tableau dynamique basée sur la quantité de texte à afficher dans cette cellule. Je l'ai résolu de cette façon:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!isLoading)
{
if ([self.conditionsDataArray count]>0)
{
Conditions *condition =[self.conditionsDataArray objectAtIndex:indexPath.row];
int height;
UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 236, 0)]; //you can set your frame according to your need
textview.text = condition.comment;
textview.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[tableView addSubview:textview];
textview.hidden = YES;
height = textview.contentSize.height;
NSLog(@"TEXT VIEW HEIGHT %f", textview.contentSize.height);
[textview removeFromSuperview];
[textview release];
return height;
}
return 55; //Default height, if data is in loading state
}
Notez que la vue texte a été ajoutée en tant que sous-vue, puis masquée. Assurez-vous donc de l'ajouter en tant que sous-vue, sinon sa hauteur ne sera pas prise en compte.
Je viens d'écrire sur ce problème et l'approche que j'ai finalement choisie. Vous pouvez lire à ce sujet ici: Hauteur de cellule UITableView dynamique basée sur le conten
Fondamentalement, j'ai créé une sous-classe UITableView qui gère tout cela pour les cellules par défaut et personnalisées. Il a probablement besoin d'être peaufiné, mais je l'ai utilisé tel quel avec un bon résultat.
Vous pouvez récupérer le code ici: https://github.com/danielsaidi/DSTableViewWithDynamicHeight
J'espère que ça aide (... et si ce n'est pas le cas, je m'excuse et j'aimerais entendre pourquoi pas)