基于JSON文件中的内容文本,使用UILabel调整自定义单元格大小

我正在parsing一个JSONstring到一个自定义表格视图单元格。 如何调整标签的高度以适应内容文本,并调整单元格的大小以适应其内容。

代码:

#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 

所以我希望单元格的大小调整为标题标签的大小加上文本标签“message”: [movie objectForKey:@"message"];

我怎样才能做到这一点?

这是根据每个indexPath的文本长度调整单元格高度的完整代码:

.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 

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

确保您的自定义单元格“ParseFeedCell”的Autolayoutclosures(未检查):

自动布局

还要将文本UILabel的数改为999999,所以不限于行。 我相信,通过一些研究,你可以find一种方法来知道文本是多less行,并以编程方式将这些行分配给UILabel。

将其用于dynamic大小的单元格:

首先定义以下内容:

 #define FONT_SIZE 13.0f #define CELL_CONTENT_WIDTH 290.0f #define CELL_CONTENT_MARGIN 19.0f 
  1. 实施下面的帮手方法;

      -(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. 在你的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. 在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; } 

如果您希望单元格基于JSON的内容进行调整,则必须更改以下方法:

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

您将每个单元格的高度设置为124px。 你应该做什么,而不是:

  1. 获取使用指定的约束条件渲染的string的大小。
  2. 重置包含该string的标签的框架
  3. tableView中的单元格返回正确的大小:heightForRowAtIndexPath:

希望能帮助到你! 干杯