कस्टम UITableViewCells ऊँचाई सेट करना


222

मैं एक कस्टम UITableViewCell का उपयोग कर रहा हूं जिसमें कुछ लेबल, बटन और छवि दृश्य प्रदर्शित होने हैं। सेल में एक लेबल है जिसका टेक्स्ट एक NSStringऑब्जेक्ट है और स्ट्रिंग की लंबाई चर हो सकती है। इस के कारण, मैं में सेल करने के लिए एक निरंतर ऊंचाई निर्धारित नहीं कर सकते UITableViewकी heightForCellAtIndexविधि। सेल की ऊँचाई लेबल की ऊँचाई पर निर्भर करती है जिसे NSString'एस' sizeWithFontपद्धति का उपयोग करके निर्धारित किया जा सकता है । मैंने इसका उपयोग करने की कोशिश की, लेकिन ऐसा लग रहा है कि मैं कहीं गलत हो रहा हूं। इसका समाधान कैसे किया जा सकता है?

यहाँ सेल को इनिशियलाइज़ करने के लिए इस्तेमाल किया गया कोड है।

if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier])
{
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    UIImage *image = [UIImage imageNamed:@"dot.png"];
    imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame = CGRectMake(45.0,10.0,10,10);

    headingTxt = [[UILabel alloc] initWithFrame:   CGRectMake(60.0,0.0,150.0,post_hdg_ht)];
    [headingTxt setContentMode: UIViewContentModeCenter];
    headingTxt.text = postData.user_f_name;
    headingTxt.font = [UIFont boldSystemFontOfSize:13];
    headingTxt.textAlignment = UITextAlignmentLeft;
    headingTxt.textColor = [UIColor blackColor];

    dateTxt = [[UILabel alloc] initWithFrame:CGRectMake(55.0,23.0,150.0,post_date_ht)];
    dateTxt.text = postData.created_dtm;
    dateTxt.font = [UIFont italicSystemFontOfSize:11];
    dateTxt.textAlignment = UITextAlignmentLeft;
    dateTxt.textColor = [UIColor grayColor];

    NSString * text1 = postData.post_body;
    NSLog(@"text length = %d",[text1 length]);
    CGRect bounds = [UIScreen mainScreen].bounds;
    CGFloat tableViewWidth;
    CGFloat width = 0;
    tableViewWidth = bounds.size.width/2;
    width = tableViewWidth - 40; //fudge factor
    //CGSize textSize = {width, 20000.0f}; //width and height of text area
    CGSize textSize = {245.0, 20000.0f}; //width and height of text area
    CGSize size1 = [text1 sizeWithFont:[UIFont systemFontOfSize:11.0f]
                        constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];

    CGFloat ht = MAX(size1.height, 28);
    textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];
    textView.text = postData.post_body;
    textView.font = [UIFont systemFontOfSize:11];
    textView.textAlignment = UITextAlignmentLeft;
    textView.textColor = [UIColor blackColor];
    textView.lineBreakMode = UILineBreakModeWordWrap;
    textView.numberOfLines = 3;
    textView.autoresizesSubviews = YES;

    [self.contentView addSubview:imageView];
    [self.contentView addSubview:textView];
    [self.contentView addSubview:webView];
    [self.contentView addSubview:dateTxt];
    [self.contentView addSubview:headingTxt];
    [self.contentView sizeToFit];

    [imageView release];
    [textView release];
    [webView release];
    [dateTxt release];
    [headingTxt release];
}

यह वह लेबल है जिसकी ऊँचाई और चौड़ाई गलत हो रही है:

textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];

जवाबों:


499

आपका UITableViewDelegateअमल होना चाहिएtableView:heightForRowAtIndexPath:

उद्देश्य सी

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [indexPath row] * 20;
}

स्विफ्ट 5

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return indexPath.row * 20
}

आप शायद का उपयोग करना चाहते जाएगा NSStringकी sizeWithFont:constrainedToSize:lineBreakMode:बस indexPath पर कुछ मूर्खतापूर्ण गणित प्रदर्शन की अपेक्षा अपनी पंक्ति की ऊँचाई गणना करने के लिए विधि :)


1
क्या आपका मतलब [indexPath पंक्ति] + 20 नहीं है?
पूर्वाह्न 22:10

11
फुल्वियो: नहीं, बिंदु यह था कि पंक्तियों को स्पष्ट रूप से अलग-अलग ऊंचाइयों पर पहुंचाना है।
रॉटरीच

5
एक विशिष्ट ऊँचाई पर सेट करने के लिए (जैसे, ४४ पिक्सेल): ४४ पर लौटें;
प्रातः

क्या आप इस आकार का उपयोग करने के बारे में कुछ और जानकारी प्रदान कर सकते हैं ।FontFont: constrainedToSize: lineBreakMode:? मेरे पास अपने सेल में एक टेक्स्ट व्यू है, और मैं इसकी ऊंचाई ऊँचाई में पाना चाहता हूँ। RorAowItIndexPath: पंक्ति की ऊँचाई निर्धारित करने के लिए, लेकिन मुझे नहीं पता कि इसे कैसे प्राप्त किया जाए! धन्यवाद
rdurand

यदि आप "[अनुक्रमणिका पंक्ति] * (कुछ-मान)" वापस करते हैं, तो पहला सेल दिखाई नहीं दे सकता है क्योंकि पहले मूल्य यह रिटर्न शून्य है। इसलिए बेहतर है कि आप आवश्यक सेल की ऊँचाई की गणना करें और उस गणना मान को यहाँ वापस
विनायक जीएच

134

यदि आपकी सभी पंक्तियाँ समान ऊँचाई की हैं, तो बस rowHeightइसे लागू करने के बजाय UITableView की संपत्ति सेट करें heightForRowAtIndexPath। Apple डॉक्स:

तालिका दृश्य का उपयोग करने के लिए प्रदर्शन निहितार्थ हैं: heightForRowAtIndexPath: rowHeight के बजाय। जब भी कोई तालिका दृश्य प्रदर्शित किया जाता है, तो वह tableView: heightForRowAtIndexPath: को उसकी प्रत्येक पंक्तियों के प्रतिनिधि पर कॉल करता है, जिसके परिणामस्वरूप बड़ी संख्या में पंक्तियों (लगभग 1000 या अधिक) वाले तालिका दृश्य के साथ एक महत्वपूर्ण प्रदर्शन समस्या हो सकती है।


5
यह पूरी तरह से ठीक काम करता है जब सभी पंक्तियों की ऊंचाई समान होती है। मूल पोस्टर, हालांकि, उस स्थिति में नहीं है, इसलिए अपने आप में उत्तर गलत नहीं है, लेकिन मूल प्रश्न का उत्तर नहीं देता है। फिर भी, मुझे यह नोट करना महत्वपूर्ण है कि रोइंगाइट की स्थापना करने की संभावना सबसे अधिक है, जो उंचाई की ऊंचाई से बेहतर प्रदर्शन देता है, वह यह है कि स्क्रॉलबार के आयामों की गणना करने वाली चीजें O (1) के बजाय O (n) है।
डैनियल एल्बसचैट

2
ध्यान दें (स्पष्ट कारणों के लिए) कि यदि tableView.rowHeightसेट किया गया है, तो heightForRowAtIndexPathकॉल नहीं किया जाएगा, यदि आप यह पता लगाने की कोशिश कर रहे हैं कि (जैसा कि मैं क्यों था)।
devios1

25

एक कस्टम UITableViewCell -controller में यह जोड़ें

-(void)layoutSubviews {  

    CGRect newCellSubViewsFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    CGRect newCellViewFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);

    self.contentView.frame = self.contentView.bounds = self.backgroundView.frame = self.accessoryView.frame = newCellSubViewsFrame;
    self.frame = newCellViewFrame;

    [super layoutSubviews];
}

UITableView -controller में इसे जोड़ें

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [indexPath row] * 1.5; // your dynamic height...
}

CGRect newCellSubViewsFrame = self.bounds; CGRect newCellViewFrame = self.frame;
पिज़ाओला गोर्गोन्जोला

17
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 300.0f
#define CELL_CONTENT_MARGIN 10.0f

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath      *)indexPath;
{
   /// Here you can set also height according to your section and row
   if(indexPath.section==0 && indexPath.row==0)
   {
     text=@"pass here your dynamic data";

     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, 44.0f);

     return height + (CELL_CONTENT_MARGIN * 2);
   }
   else
   {
      return 44;
   }
}

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    UILabel *label = nil;

    cell = [tv dequeueReusableCellWithIdentifier:@"Cell"];
    if (cell == nil)
    {
       cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"];
    }
    ********Here you can set also height according to your section and row*********
    if(indexPath.section==0 && indexPath.row==0)
    {
        label = [[UILabel alloc] initWithFrame:CGRectZero];
        [label setLineBreakMode:UILineBreakModeWordWrap];
        [label setMinimumFontSize:FONT_SIZE];
        [label setNumberOfLines:0];
        label.backgroundColor=[UIColor clearColor];
        [label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
        [label setTag:1];

        // NSString *text1 =[NSString stringWithFormat:@"%@",text];

        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        if (!label)
        label = (UILabel*)[cell viewWithTag:1];


        label.text=[NSString stringWithFormat:@"%@",text];
        [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH          - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
        [cell.contentView addSubview:label];
    }
return cell;
}

8
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    CGSize constraintSize = {245.0, 20000}
    CGSize neededSize = [ yourText sizeWithFont:[UIfont systemFontOfSize:14.0f] constrainedToSize:constraintSize  lineBreakMode:UILineBreakModeCharacterWrap]
if ( neededSize.height <= 18) 

   return 45
else return neededSize.height + 45 
//18 is the size of your text with the requested font (systemFontOfSize 14). if you change fonts you have a different number to use  
// 45 is what is required to have a nice cell as the neededSize.height is the "text"'s height only
//not the cell.

}

8

मैंने बहुत सारे समाधान देखे लेकिन सभी गलत या अनपेक्षित थे। आप 5 समस्याओं को viewDidLoad और autolayout में 5 लाइनों के साथ हल कर सकते हैं। यह आज्ञाकारी सी के लिए:

_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) ;

तेजी से 2.0 के लिए:

 self.tableView.estimatedRowHeight = 80
 self.tableView.rowHeight = UITableViewAutomaticDimension      
 self.tableView.setNeedsLayout()
 self.tableView.layoutIfNeeded()
 self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)

अब अपने सेल को अपने स्टोरीबोर्ड में xib या मेज़पोश के साथ बनाएं। इसके साथ आपको अधिक या ओवरराइड को लागू करने की कोई आवश्यकता नहीं है। (डॉन नंबर ओएस लाइन्स को भूल जाओ) और नीचे का लेबल (अड़चन) डाउनग्रेड करें "कंटेंट हगिंग प्रायरिटी - वर्टिकल टू 250"

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें

आप अगले url में कोड को लोड कर सकते हैं: https://github.com/joses22/exampleTableCellChight


1
2 दिनों में मैं एक ही सेल के साथ और भी इमेजेज लगाऊंगा ImageView, और अन्य सबटेबिलिटी के साथ यह तरीका हमेशा काम करता है। वास्तव में +1 के लिए धन्यवाद।
जोस

एक दम बढ़िया!! यह दूसरों को भी मदद करेगा। धन्यवाद :)
जगदीश

इसलिए, जैसा कि वादा किया गया है, यहां आपके पास नया कोड और एक नई छवि है।
जोस पोज

बहुत बहुत धन्यवाद ... इसे जारी रखें ...
जगदीश 6:24 बजे

यदि आप UITableViewCell को प्रोग्रामेटिक रूप से बना रहे हैं तो यह समाधान काम नहीं करता है। जैसे कि इंटरफ़ेस बिल्डर का उपयोग नहीं करना
MB_iOSDeveloper

6

पंक्ति ऊंचाई और अनुमानित पंक्ति ऊंचाई के लिए स्वचालित आयाम सेट करने के लिए, निम्न चरणों को सुनिश्चित करें, सेल / पंक्ति ऊंचाई लेआउट के लिए ऑटो आयाम प्रभावी।

  • टेबलव्यू डेटास्रोत और प्रतिनिधि को असाइन करें और लागू करें
  • UITableViewAutomaticDimensionरोहाइट और अनुमानित रोवेहाइट को असाइन करें
  • प्रतिनिधि / डेटा स्रोत विधियों को लागू करें (अर्थात इसका heightForRowAtमान लौटाएं UITableViewAutomaticDimension)

-

उद्देश्य सी:

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

स्विफ्ट:

@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
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension
}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

UITableviewCell में लेबल उदाहरण के लिए

  • पंक्तियों की संख्या निर्धारित करें = 0 (और पंक्ति विराम मोड = छोटी पूंछ)
  • अपने पर्यवेक्षक / सेल कंटेनर के संबंध में सभी बाधाओं (ऊपर, नीचे, दाएं बाएं) को सेट करें।
  • वैकल्पिक : लेबल के लिए न्यूनतम ऊंचाई सेट करें, यदि आप लेबल द्वारा कवर किया गया न्यूनतम ऊर्ध्वाधर क्षेत्र चाहते हैं, भले ही कोई डेटा न हो।

यहां छवि विवरण दर्ज करें

नोट : यदि आपने डायनामिक लंबाई के साथ एक से अधिक लेबल (यूआईईएल) लगाए हैं, जिसे इसकी सामग्री के आकार के अनुसार समायोजित किया जाना चाहिए: लेबल के लिए 'कंटेंट हगिंग और कम्प्रेशन रेसिस्टेंस प्रायोरिटी' को समायोजित करें जिसे आप उच्च प्राथमिकता के साथ विस्तारित / संपीड़ित करना चाहते हैं।

इस उदाहरण में मैंने कम हगिंग और उच्च संपीड़न प्रतिरोध प्राथमिकता निर्धारित की है, जो दूसरी (पीली) लेबल की सामग्री के लिए अधिक प्राथमिकता / महत्व निर्धारित करती है।

यहां छवि विवरण दर्ज करें


5

इस विषय पर सभी पदों के लिए धन्यवाद, UITableViewCell की पंक्तिहाइट को समायोजित करने के लिए वास्तव में कुछ उपयोगी तरीके हैं।

यहां उन सभी में से कुछ अवधारणाओं का संकलन है जो वास्तव में iPhone और iPad के लिए निर्माण करते समय मदद करता है। आप अलग-अलग वर्गों तक भी पहुँच सकते हैं और उन्हें विभिन्न आकारों के अनुसार समायोजित कर सकते हैं।

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

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
    int cellHeight = 0;

    if ([indexPath section] == 0) 
    {
        cellHeight = 16;
        settingsTable.rowHeight = cellHeight;
    }
    else if ([indexPath section] == 1)
    {
        cellHeight = 20;
        settingsTable.rowHeight = cellHeight;
    }

    return cellHeight;
}
else
{
    int cellHeight = 0;

    if ([indexPath section] == 0) 
    {
        cellHeight = 24;
        settingsTable.rowHeight = cellHeight;
    }
    else if ([indexPath section] == 1)
    {
        cellHeight = 40;
        settingsTable.rowHeight = cellHeight;
    }

    return cellHeight;
}
return 0;
} 

एक्सकोड में विश्लेषण करते समय, लाइन "इंट सेलहाइट;" लॉजिक एरर बनाया, "अनफिनिश्ड या गारबेज वैल्यू कॉलर को लौटाया।" सेलहाईट को 0 पर सेट करके, इसने त्रुटि को ठीक किया। यह त्रुटि तब भी दिखाई देगी यदि आपने NSString को एक स्विच स्टेटमेंट के अंदर शून्य करने के लिए सेट नहीं किया है, तो ऊपर दिए गए स्टेटमेंट के समान / अन्यथा।
Whyoz

3

डायनामिक सेल की ऊँचाई होने के लिए जैसे ही लेबल का पाठ बढ़ता है, आपको पहले ऊँचाई की गणना करने की आवश्यकता होती है, कि पाठ -heightForRowAtIndexPathप्रतिनिधि पद्धति में उपयोग करने वाला है और इसे अन्य लैब्स, छवियों की अतिरिक्त ऊँचाइयों (पाठ की अधिकतम ऊंचाई + अन्य स्थैतिक की ऊँचाई) के साथ लौटाता है इटैलिकनेट) और सेल निर्माण में समान ऊंचाई का उपयोग करें।

#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 300.0f  
#define CELL_CONTENT_MARGIN 10.0f

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

    if (indexPath.row == 2) {  // the cell you want to be dynamic

        NSString *text = dynamic text for your label;

        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, 44.0f);

        return height + (CELL_CONTENT_MARGIN * 2);
    }
    else {
        return 44; // return normal cell height
    }
}

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

    static NSString *CellIdentifier = @"Cell";

    UILabel *label;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] ;
    }

    label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 280, 34)];

    [label setNumberOfLines:2];

    label.backgroundColor = [UIColor clearColor];

    [label setFont:[UIFont systemFontOfSize:FONT_SIZE]];

    label.adjustsFontSizeToFitWidth = NO;

    [[cell contentView] addSubview:label];


    NSString *text = dynamic text fro your label;

    [label setText:text];

    if (indexPath.row == 2) {// the cell which needs to be dynamic 

        [label setNumberOfLines:0];

        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];

    }
    return  cell;
}

@Tisho क्या आपने इसे वोट करने के लिए टीशो ब्रो का परीक्षण किया है। ध्यान से परीक्षण करें, यह भाई काम करता है !!!!
समीर जवरचन

1
मैंने आपके उत्तर को अस्वीकार नहीं किया है। मैंने अभी स्वरूपण में सुधार किया है।
टिशो सेप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.