web-dev-qa-db-ger.com

warum funktioniert UITableViewAutomaticDimension nicht?

Hallo, es gibt viele Fragen, die die dynamische Höhe für UITableViewCell von UITableView beantworten. Ich finde es jedoch komisch, als ich es tat.

hier sind einige der Antworten:

hier und hier

normalerweise würde dies die dynamische Höhe für eine Zelle beantworten

tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension

aber in meinem Fall frage ich mich, dass diese Zeile nichts tut.

meine UITableView wird angezeigt, nachdem Sie auf die Tab-Leiste in der Teilansicht geklickt haben. Ist das hilfreich? 

Vielleicht fehlt mir etwas. Könnte mir jemand helfen, dass ich 2 Stunden lang dumm gearbeitet habe? 

Dies ist meine Einschränkung für den Titel. Der Titel könnte lang sein, das Label jedoch nicht.

enter image description here

und das ist meine Zelle

enter image description here

56
CaffeineShots

Damit UITableViewAutomaticDimension funktioniert, müssen Sie alle linken, rechten, unteren und oberen Einschränkungen relativ zur Zellcontaineransicht festlegen. In Ihrem Fall müssen Sie der Superview-Einschränkung für die Beschriftung unter dem Titel den fehlenden unteren Platz hinzufügen

126
Zell B.

Ich hatte Einschränkungen programmgesteuert hinzugefügt und sie versehentlich der Zelle direkt hinzugefügt, d. H. Nicht in der Eigenschaft contentView. Das Hinzufügen der Einschränkungen zu contentView hat es für mich gelöst!

21
Eyeball

Stellen Sie außerdem sicher, dass die Zeilen für Ihr UILabel in der Zelle auf 0 festgelegt sind. Wenn es auf 1 gesetzt ist, wächst es nicht vertikal. 

16
CamQuest

Stellen Sie zum Festlegen der automatischen Bemaßung für die Zeilenhöhe und die geschätzte Zeilenhöhe die folgenden Schritte ein, um die automatische Bemaßung für das Layout der Zellen-/Zeilenhöhe wirksam zu machen. 

  • Weisen Sie TableView-Datenquellen und Delegaten zu und implementieren Sie sie
  • Weisen Sie UITableViewAutomaticDimension rowHeight & geschätzteRowHeight zu
  • Implementieren Sie Delegate/dataSource-Methoden (d. H. heightForRowAt und geben Sie einen Wert UITableViewAutomaticDimension zurück).

-

Ziel c:

// in ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

  @property IBOutlet UITableView * table;

@end

// in ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.table.dataSource = self;
    self.table.delegate = self;

    self.table.rowHeight = UITableViewAutomaticDimension;
    self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return UITableViewAutomaticDimension;
}

Swift:

@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
}

Für die Labelinstanz in UITableviewCell

  • Setze Zeilenanzahl = 0 (& Zeilenumbruchmodus = Ende abschneiden)
  • Legen Sie alle Einschränkungen (oben, unten, rechts links) in Bezug auf den Superview-/Zellencontainer fest.
  • Optional: Legen Sie die Mindesthöhe für die Beschriftung fest, wenn Sie möchten, dass der vertikale Mindestbereich durch die Beschriftung abgedeckt wird, auch wenn keine Daten vorhanden sind.

enter image description here

Hinweis : Wenn Sie mehr als ein Label (UIElements) mit dynamischer Länge haben, das entsprechend seiner Inhaltsgröße angepasst werden sollte: Passen Sie 'Content Hugging und Compression Resistance Priority' für Labels an, mit denen Sie expandieren/komprimieren möchten Höhere Priorität.

14
Krunal

Seit iOS 11 und Xcode 9.3 sind die meisten der oben genannten Informationen falsch. Apples Guide schlägt die Einstellung vor

    tableView.estimatedRowHeight = 85.0
    tableView.rowHeight = UITableViewAutomaticDimension

WWDC 2017 session 245 (Erstellen von Apps mit dynamischem Typ, etwa 16:33 Uhr im Video) schlägt etwas ähnliches vor. Nichts davon machte für mich einen Unterschied.

Für eine Zelle im Untertitelstil müssen Sie nur die Zellen für sich selbst ändernde Tabellenansicht anzeigen, indem Sie die Anzahl der Zeilen (im Beschriftungsabschnitt des Attribut-Inspektors) für Titel und Untertitel auf 0 setzen. Wenn eine dieser Beschriftungen zu lang ist und Sie die Anzahl der Zeilen nicht auf 0 setzen, wird die Größe der Tabellenzelle nicht angepasst.

4
Zampano

Ich habe einen speziellen Fall, und 99% der Lösungen, die ich gelesen habe, funktionierten nicht. Ich dachte, ich würde meine Erfahrungen teilen. Ich hoffe, es kann helfen, da ich vor der Behebung dieses Problems ein paar Stunden gekämpft habe. 

Mein Szenario

  • Ich verwende zwei TableViews in einem ViewController
  • Ich bin Custom Cells (xib) in diesen Tabellenansichten laden
  • Dynamischer Inhalt in Zellen besteht aus zwei Labels
  • Seite verwendet ein ScrollView

Was ich brauchte um zu erreichen:

  • Dynamische TableView-Höhe
  • Dynamische TableViewCells-Höhe

Was Sie überprüfen müssen, damit es reibungslos funktioniert:

  • Wie Sie in jedem Lernprogramm und in jeder Antwort erfahren, legen Sie alle Einschränkungen für Ihr Label/Ihren Inhalt (oben, unten, vorne und hinten) fest und setzen Sie ihn auf ContentView (Superview). Dieses Video-Tutorial wird hilfreich sein .

  • In der viewWillAppear-Methode meines ViewControllers gebe ich einer meiner tableViews (tableView2) eine geschätzte Zeilenhöhe und verwende dann die UITableViewAutomaticDimension als solche (und wie in allen Tutorials/Antworten zu sehen): 

        override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        tableView2.estimatedRowHeight = 80
        tableView2.rowHeight = UITableViewAutomaticDimension
    
    }
    

Für mich waren diese vorherigen Schritte nicht genug. Meine TableView würde einfach die geschätzteRowHeight nehmen und mit der Anzahl der Zellen multiplizieren. Meeeh.

  • Da ich zwei verschiedene TableViews verwende, habe ich für jede eine Outlet erstellt, tableView1 und tableView2. Ich erlaube mir, sie in der viewDidLayoutSubviews-Methode zu skalieren. Fühlen Sie sich frei zu fragen, wie ich das gemacht habe.

  • Ein zusätzlicher Schritt hat es für mich behoben, indem es der viewDidAppear-Methode Folgendes hinzugefügt hat:

    override func viewDidAppear(_ animated: Bool) {
    tableView1.reloadData() // reloading data for the first tableView serves another purpose, not exactly related to this question.
    tableView2.setNeedsLayout()
    tableView2.layoutIfNeeded()
    tableView2.reloadData()
    }
    

Hoffe das hilft jemandem!

4
Bptstmlgt

Vergessen, tableView(heightForRowAt:indexPath:) zu entfernen

Es könnte der Fall sein, dass Sie wie ich versehentlich vergessen, zu entfernen den Speichercode für die heightForRowAt-Methode _ _ 

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 60.0
}
3
Guy Daher

Versuchen Sie es mit dieser einfachen Lösung, die für mich funktioniert.

In viewDidLoad schreibe diesen Code,

-(void)viewDidLoad 
{
[super viewDidLoad];
 self.tableView.estimatedRowHeight = 100.0; // for example. Set your average height
 self.tableView.rowHeight = UITableViewAutomaticDimension;
}

In cellForRowAtIndexPath schreibe diesen 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;
 }
2
Jaywant Khedkar

In meinem Fall hatte ich zwei UITableViews, die ich als ändern musste

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    CGFloat height = 0.0;
    if (tableView == self.tableviewComments) {
        return UITableViewAutomaticDimension;
    }else if (tableView == self.tableViewFriends) {
        height = 44.0;
    }
    return height;
}
2
user1994956

Für alle, die vielleicht das gleiche Problem mit mir hatten: Ich habe eine Stunde lang gekämpft, damit es funktioniert. Ein einfaches UIlabel mit Einschränkungen für oben, unten links und rechts. Ich habe die willDisplayCell verwendet, um die Daten an die Zelle zu übergeben, und dies verursachte Probleme bei der Zellenhöhe. Solange ich diesen Code in cellForRow einfügte, funktionierte alles einwandfrei. Ich habe nicht verstanden, warum dies passiert ist. Möglicherweise wurde die Zellenhöhe berechnet, bevor willDisplayCell aufgerufen wurde, sodass kein Inhalt für die richtige Berechnung vorhanden war. Ich wollte nur erwähnen und wahrscheinlich jemandem mit dem gleichen Problem helfen.

1
Thomas

Für mein Setup habe ich zuerst überprüft, ob die Einschränkungen im Storyboard UITableViewCell eindeutig von oben nach unten waren und dann den Code an zwei Stellen ändern mussten. 

  1. UITableViewDelegatetableView(_:heightForRowAt:)

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
        // return UITableViewAutomaticDimension for older than Swift 4.2
    }
    
  2. UITableViewDelegatetableView(_:estimatedHeightForRowAt:)

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
        // return UITableViewAutomaticDimension for older than Swift 4.2
    }
    

In Schritt 1 und 2 können Sie die automatische Größenänderung nur für bestimmte Zeilen anwenden. Für die Anwendung auf die gesamte UITableView verwenden Sie: 

tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = UITableView.automaticDimension
// return UITableViewAutomaticDimension for older than Swift 4.2
0
Pranav Kasetti

Ich hatte drei horizontale Elemente und die meisten links hatten eine Einschränkung nach links, der mittlere hatte oben, unten, links und rechts. Der rechte hatte einen rechten und links den mittleren Punkt. Die Lösung bestand darin, dem mittleren Element (meinem Label) zusätzliche linke und rechte Beschränkungen hinzuzufügen, die der Zelle eine> = Zahl waren.

0
user3739902

Damit UITableViewAutomaticDimension funktioniert, müssen Sie sicherstellen, dass alle Einschränkungen der 4 Ecken zum Superview hinzugefügt werden. In den meisten Fällen funktioniert es gut mit UILabel, aber manchmal finde ich UITextView, wenn UILabel zur Zeit nicht gut funktioniert. Versuchen Sie daher, zu UITextView zu wechseln, und stellen Sie sicher, dass Scrolling Enabled im Storyboard deaktiviert ist, oder Sie können es auch programmgesteuert festlegen.

0
Terry Tan

Ich habe eine neue Lösung ... das hat für mich funktioniert.

grundsätzlich UITableViewAutomaticDimension umbenannt in UITableView.automaticDimension... ich hoffe..es wo

Stellen Sie sicher, dass alle Ansichten in der Zelle auf die Inhaltsansicht und nicht auf die Zelle beschränkt sind. 

Wie Apple sagt:

inhalt der Tabellenansicht-Zelle in der Inhaltsansicht der Zelle Um die Höhe der Zelle festzulegen, benötigen Sie eine ununterbrochene Kette von Einschränkungen und Ansichten (mit definierten Höhen), um den Bereich zwischen der oberen Kante der Inhaltsansicht und der unteren Kante auszufüllen.

0
fullMoon

in iOS 11 und höher funktionierte es einwandfrei, während in iOS 10 das Hinzufügen der Lösung das Ziel war

table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = 200 // a number and not UITableView.automaticDimension

stellen Sie außerdem sicher, dass Sie "heightForRowAt" hinzufügen, auch wenn es in iOS 11 und höher funktioniert. Es wird benötigt, wenn Sie iOS 10 unterstützen

   func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
0
Bassant Ashraf