2013-10-06 14 views
17

Ich habe eine UITableview mit mehreren wiederverwendbaren TableViewCells. In einer Zelle habe ich eine UITextView, die sich an ihren Inhalt anpasst. Jetzt muss ich "nur" die Größe contentView der TableViewCell ändern, damit ich den while-Text lesen kann. Ich habe bereits versucht:Wie wird die Größe von UITableViewCell an den Inhalt angepasst?

cell2.contentView.bounds.size.height = cell2.discriptionTextView.bounds.size.height; 

Oder:

cell2.contentView.frame = CGRectMake(0, cell2.discriptionTextView.bounds.origin.y,  
cell2.discriptionTextView.bounds.size.width,  
cell2.discriptionTextView.bounds.size.height); 

Bei dem Verfahren:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath 
*)indexPath {} 

Aber es wird nicht funktionieren.

Weiß jemand, wie man das macht?

Neuer 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; 
    } 

Antwort

7

Sie müssen implementieren heightForRowAtIndexPath.

Angenommen, die Daten, die im textView angezeigt werden sollen, werden in einem NSArray gespeichert.

- (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 

} 
+0

OK, ich habe jetzt Ihren Code hinzugefügt, und es funktioniert, aber nur das zweite Mal, wenn Sie den UIViewController anzeigen. Ich habe einen CGFloat erstellt und dann die Höhe des UITextView dem CGFloat zugewiesen. Dann gebe ich das erstellte CGFloat in der oben beschriebenen Methode zurück. Ich werde meinen neuen Code oben veröffentlichen. –

+0

erste Sache, die Sie wissen sollten ist, dass Sie Höhe nicht gesetzt haben für die Zelle in ‚cellForRowAtIndexPath‘ Es sollte in ‚heightForRowAtIndexPath‘ zweite Sache geschehen ist, dass ‚heightForRowAtIndexPath‘ vor ‚cellForRowAtIndexPath‘ genannt wird. Das bedeutet, dass Sie die Höhe für eine Zelle berechnen müssen, bevor Sie dieselbe Zelle auffüllen (Die Tabelle sollte über die Höhe informiert werden, bevor Sie die Zelle auffüllen – dRAGONAIR

+0

Hinweis: Alle 'UILineBreakMode *' sind veraltet, ersetzt durch 'NSLineBreakBy *' though. – Raptor

16

Sie können nur eine UITableViewCell in tableView:heightForRowAtIndexPath: Delegatmethode ändern.

Sie müssen abschätzen, wie groß der Text sein wird, wenn diese Methode für jede Zeile aufgerufen wird, wenn die TabelleView geladen wird.

Dies ist, was ich getan habe, um das Problem zu lösen.

-(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; 
    } 

EDIT

Während ich diese Lösung für eine Weile benutzt, fand ich eine optimalere, die ich als es empfehlen würde erfordern nicht einen ganzen Textview, um die Zuweisung zu arbeiten, und Text kann größer als 2000 sein.

-(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; 
} 
+0

Bitte werfen Sie einen Blick auf meinen neu hinzugefügten Code oben. –

+0

Was versuchst du zu tun? Größe der contentView des textView oder der Zelle? – AdamG

+1

Die Methode, die ich oben gezeigt habe, erlaubt es Ihnen, die Größe der Zelle selbst basierend auf der Größe der contentView einer gegebenen textView in einer Zelle neu zu bestimmen. Alles, was Sie tun müssen, ist den Text zu finden, den Sie für die angegebene Zelle verwenden. – AdamG

12

Hier ist eine aktualisierte Version für iOS 7+, die Reiniger (keine zusätzliche Methode) ist

-(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; 
    } 
2

Dieser Thread ist schon eine ganze Weile gewesen, aber in iOS 8 UITableViewAutomaticDimension eingeführt wurde. Sie müssen Constraints wie eine Scroll-Ansicht vom oberen zum unteren Rand der Zelle setzen, damit dies funktioniert. Aber danach, fügen Sie einfach den folgenden Code viewDidLoad():

tableView.rowHeight = UITableViewAutomaticDimension 
tableView.estimatedRowHeight = 122.0 

Stellen Sie sicher, Ihre geschätzten Höhe wie möglich an der Realität so nah ist sonst werden Sie einige Buggy Scrollen erhalten.

12

Wie @Rob Norback sagte, gibt es etwas namens UITableViewAutomaticDimension.

Für Swift, der einfachste Weg, Inhalt von UITableViewCell im laufenden Betrieb Größe zu ändern, ist es, dies einfach hinzuzufügen.

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return UITableViewAutomaticDimension 
} 

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return UITableViewAutomaticDimension 
} 
+0

Dank. nach vielen anderen Beiträge der Lektüre dieses wirklich funktioniert. – petrsyn

+0

können Sie gerne @petrsyn! –

+3

dies nicht für mich arbeiten. – DeyaEldeen

1

I this solution of Jure

  • Erste bevorzugen, setzen Einschränkungen Textview mit seinem Super gepinnt werden (Zelle content in diesem Fall). Implementieren UITextViewDelegate wie diese
  • Disable textView.scrollEnabled
  • Set

    table.rowHeight = UITableViewAutomaticDimension; 
    tableView.estimatedRowHeight = 44; 
    

    Wenn schließlich der Code nicht funktioniert, dies dann statt

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
        return UITableViewAutomaticDimension; 
    } 
    
    - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { 
        return 44; 
    } 
    
  • verwenden:

    - (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]; 
        } 
    
+0

Alle anderen Beispiele ohne Storyboards? –

1

Das Hinzufügen dieser zwei Methoden zu ViewController mit UITableViewAutomaticDimension sollte den Trick machen. Es hat für mich beim Einbetten eines UITextView in eine UITableViewCell mit variabler Länge funktioniert.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return UITableViewAutomaticDimension; 
} 

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return UITableViewAutomaticDimension; 
} 
0

Bei UILabel Subview in der UITableViewCell, erreichte ich Autoskal des Etiketts nur durch die Zwänge des Labels Einstellung (mit Storyboard, Xcode 8.3.2).

Dies funktioniert, da anscheinend das Standardverhalten des Labels und der Zelle sizeToFit ist. Dasselbe sollte auch für UITextView funktionieren.

Verwandte Themen