简体   繁体   English

根据JSON文件中的内容文本调整带有UILabel的自定义单元格的大小

[英]Resize Custom cell with a UILabel on it based on content text from JSON file

I'm parsing a JSON string into a custom table view cell. 我正在将JSON字符串解析为自定义表格视图单元格。 How can I resize the label's height to fit the content text and also resize the cell to fit it's content. 如何调整标签的高度以适合内容文本,以及如何调整单元格以适合其内容。

The code: 编码:

#import "DEMOSecondViewController.h"
#import "DEMONavigationController.h"
#import "PostsObject.h"
#import "RNBlurModalView.h"
#import "AFNetworking.h"

@interface DEMOSecondViewController ()

@end

@implementation DEMOSecondViewController
@synthesize tableView = _tableView, activityIndicatorView = _activityIndicatorView, movies = _movies;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"iCelebri.com";
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Menu"
                                                                             style:UIBarButtonItemStylePlain
                                                                            target:(DEMONavigationController *)self.navigationController
                                                                            action:@selector(showMenu)];

    self.tableView.separatorColor = [UIColor clearColor];

    // Setting Up Activity Indicator View
    self.activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    self.activityIndicatorView.hidesWhenStopped = YES;
    self.activityIndicatorView.center = self.view.center;
    [self.view addSubview:self.activityIndicatorView];
    [self.activityIndicatorView startAnimating];
    self.tableView.separatorColor = [UIColor clearColor];

    // Initializing Data Source
    self.movies = [[NSArray alloc] init];

    [self makeConnection];

}

-(void)makeConnection {
    _url = [[NSURL alloc] initWithString:@"my-site.com/json.php?name=Name"];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:_url];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        self.movies = JSON;
        [self.activityIndicatorView stopAnimating];
        [self.tableView reloadData];

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
    }];

    [operation start];
}

// Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (self.movies && self.movies.count) {
        return self.movies.count;
    } else {
        return 0;
    }
}

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

- (void)tableView:(UITableView *)tableView
  willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setBackgroundColor:[UIColor clearColor]];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *simpleTableIdentifier = @"PostsObject";

    PostsObject *cell = (PostsObject *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"PostsObject" owner:self options:nil];
        cell = [nib objectAtIndex:0];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];

        self.tableView.backgroundView = imageView;
    }

    NSDictionary *movie = [self.movies objectAtIndex:indexPath.row];
    cell.title.text = [movie objectForKey:@"message"];
    cell.published.text = [movie objectForKey:@"published"];

    return cell;
}


@end

So I want the cell to resize to the size of the title label plus text label "message": [movie objectForKey:@"message"]; 因此,我希望单元格调整为标题标签加上文本标签“ message”的大小: [movie objectForKey:@"message"];

How can I do this? 我怎样才能做到这一点?

This Is a full code for resizing the cell's height according to the text length for each indexPath: 这是一个完整的代码,用于根据每个indexPath的文本长度来调整单元格的高度:

The .h file: .h文件:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
    IBOutlet UITableView *_tableView;
    UIActivityIndicatorView *_activityIndicatorView;
    NSArray *_movies;
    CGFloat cellTextWidth;
    CGFloat cellHeightExceptText;
}
@property (nonatomic, retain) UIFont *fontForCellText;
@property (nonatomic, retain) UITableView *tableView;
@property (nonatomic, retain) UIActivityIndicatorView *activityIndicatorView;
@property (nonatomic, retain) NSArray *movies;

@end

The .m file: .m文件:

#import "ViewController.h"
#import "AFNetworking.h"
#import "ParseFeedCell.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize tableView = _tableView, activityIndicatorView = _activityIndicatorView, movies = _movies;
@synthesize fontForCellText;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ParseFeedCell" owner:self options:nil];
    ParseFeedCell *cell = [nib objectAtIndex:0];
    fontForCellText = cell.title.font;
    cellTextWidth = cell.title.frame.size.width;
    cellHeightExceptText = cell.frame.size.height - cell.title.frame.size.height;

    [self.navigationController setNavigationBarHidden:YES];

    self.tableView.separatorColor = [UIColor clearColor];

    // Setting Up Activity Indicator View
    self.activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    self.activityIndicatorView.hidesWhenStopped = YES;
    self.activityIndicatorView.center = self.view.center;
    [self.view addSubview:self.activityIndicatorView];
    [self.activityIndicatorView startAnimating];
    self.tableView.separatorColor = [UIColor clearColor];

    // Initializing Data Source
    //self.movies = [[NSArray alloc] init];

    NSURL *url = [[NSURL alloc] initWithString:@"your-website.com/json_file?name=Name"];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        self.movies = [[NSArray alloc] initWithArray:JSON];
        [self.activityIndicatorView stopAnimating];
        [self.tableView reloadData];

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
    }];

    [operation start];
}

// Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (self.movies && self.movies.count) {
        return self.movies.count;
    } else {
        return 0;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *simpleTableIdentifier = @"ParseFeedCell";

    ParseFeedCell *cell = (ParseFeedCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ParseFeedCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

    }

    NSDictionary *movie = [self.movies objectAtIndex:indexPath.row];
    NSString *strText = [movie objectForKey:@"message"];

    CGRect rect = cell.title.frame;
    rect.size.height = [self getHeightForText:strText];
    cell.title.frame = rect;
    cell.title.text = strText;
    cell.arrow.center = CGPointMake(cell.arrow.frame.origin.x, rect.origin.y + rect.size.height/2);
    cell.published.text = [movie objectForKey:@"published"];
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *movie = [self.movies objectAtIndex:indexPath.row];
    NSString *strText = [movie objectForKey:@"message"];

    CGFloat cellHeight = cellHeightExceptText + [self getHeightForText:strText];

    return cellHeight;
}

- (CGFloat)getHeightForText:(NSString *)strText
{
    CGSize constraintSize = CGSizeMake(cellTextWidth, MAXFLOAT);
    CGSize labelSize = [strText sizeWithFont:fontForCellText constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
    NSLog(@"labelSize.height = %f",labelSize.height);
    return labelSize.height;
}

Make sure that the Autolayout for your custom cell "ParseFeedCell" is off (Not Checked): 确保自定义单元格“ ParseFeedCell”的自动版式已关闭(未选中):

自动布局

Also change the number of Lines of the text UILabel to 999999 so it's not limited to lines. 另外,将文本UILabel的数更改为999999,这样就不仅限于行数。 I am sure that with a bit of research you can find a way to know how many lines the text is and assign the lines to the UILabel programatically. 我敢肯定,通过一些研究,您可以找到一种方法来了解文本的行数,并将这些行以编程方式分配给UILabel。

Use this to a dynamic sized cell: 将其用于动态尺寸的单元格:

Start by defining the following: 首先定义以下内容:

#define FONT_SIZE 13.0f 
#define CELL_CONTENT_WIDTH 290.0f 
#define CELL_CONTENT_MARGIN 19.0f 
  1. Implement the following helper method; 实现以下辅助方法;

      -(CGSize)frameForText:(NSString*)text sizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size { NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy]; paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping; NSDictionary * attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle }; CGRect textRect = [text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil]; // This contains both height and width, but we really care about height. return textRect.size; } 
  2. In your UITableViewDelegate Height method: 在您的UITableViewDelegate Height方法中:

     - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; { NSDictionary *movie = [self.movies objectAtIndex:indexPath.row]; NSString *text = [movie objectForKey:@"message"]; CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f); CGSize size = [self frameForText:text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint]; CGFloat height = MAX(size.height, 14.0f); return height + CELL_CONTENT_MARGIN; } 
  3. Set the frame and text in your UITableViews cellForRowAtIndexPath: 在您的UITableViews cellForRowAtIndexPath中设置框架和文本:

     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *simpleTableIdentifier = @"PostsObject"; PostsObject *cell = (PostsObject *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; if (cell == nil) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"PostsObject" owner:self options:nil]; cell = [nib objectAtIndex:0]; cell.selectionStyle = UITableViewCellSelectionStyleNone; UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]]; self.tableView.backgroundView = imageView; } NSDictionary *movie = [self.movies objectAtIndex:indexPath.row]; NSString *text = [movie objectForKey:@"message"]; CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f); CGSize size = [self frameForText:text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint]; cell.txtLabel.text = text; cell.txtLabel.frame = CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 14.0f)); cell.published.text = [movie objectForKey:@"published"]; return cell; } 

If you want the cell to resize based on the content of the JSON you have to change the following method: 如果要根据JSON的内容调整单元格的大小,则必须更改以下方法:

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

You're setting the height of each cell to 124px. 您正在将每个单元格的高度设置为124px。 What you should do instead it's to: 相反,您应该做的是:

  1. Get the size of the string rendered with the specified constraints. 获取使用指定约束呈现的字符串的大小。
  2. Reset the frame of the label that contains the string 重置包含字符串的标签的框架
  3. Return the right size for the cell in tableView:heightForRowAtIndexPath: 返回tableView:heightForRowAtIndexPath中单元格的正确大小

Hope it helps! 希望能帮助到你! Cheers 干杯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM