如何以编程方式增加iPhone中的UITableView单元格的高度?
我有单独的自定义UITableViewCell
显示数据(这些数据来自服务器的JSON响应)。在每个UITableViewCell
我有button阅读更多。如果用户点击阅读更多的button,我想以编程方式添加UILabel
显示来自服务器的附加信息。但最初我设置UITableViewCell
高度,所以点击阅读更多的button后,我无法看到额外的信息UILabel
..
这是屏幕截图:
这是我需要的屏幕:
这是我使用的以下编码:
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { int height1; if(readMore){ height1=200; NSLog(@"Clicked"); } else{ height1=100; NSLog(@"Not clicked"); } return height1; // Normal height } -(NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section { return [TitleArr count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { static NSString *simpleTableIdentifier = @"SimpleTableCell_iPad"; cell = (TableCell_Leads *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; } else{ static NSString *simpleTableIdentifier = @"TableCell_Leads"; cell = (TableCell_Leads *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; } if (cell == nil) { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SimpleTableCell_iPad" owner:self options:nil]; cell = [nib objectAtIndex:0]; } else{ NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TableCell_Leads" owner:self options:nil]; cell = [nib objectAtIndex:0]; } } cell.labTitle.text = [TitleArr objectAtIndex:indexPath.row]; cell.labCategory.text=[CategoryArr objectAtIndex:indexPath.row]; [cell.btnReadmore addTarget:self action:@selector(funReadmore:) forControlEvents:UIControlEventTouchUpInside]; return cell; } - (IBAction)funReadmore:(id)sender { [self.tableView beginUpdates]; readMore=TRUE; NSLog(@"READ MORE"); [self.tableView endUpdates]; }
首先采取一个bool
& int
variables。
BOOL isReadMoreButtonTouched = NO; int indexOfReadMoreButton = -1;
然后用你的代码实现
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { [[cell btnReadmore] setTag:[indexPath row]]; if(isReadMoreButtonTouched && [indexPath row]== indexOfReadMoreButton) { // design your read more label here } }
现在实施IBAction
-(IBAction) funReadmore:(id)sender { UIButton *readMoreButton = (UIButton *)sender; indexOfReadMoreButton=[readMoreButton tag]; isReadMoreButtonTouched=YES; [[self tableView] beginUpdates]; [[self tableView] reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForItem: indexOfReadMoreButton inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic]; [[self tableView] endUpdates]; }
现在来到heightForRowAtIndexPath
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if(isReadMoreButtonTouched && [indexPath row]== indexOfReadMoreButton) return 200.0f; else return 100.0f; }
希望它能为你工作。
采取int readMoreAtIndex;
作为你的类variables。 在init method
和/或viewDidLoad/viewWillAppear
中用负值(如-1)初始化它。 一些基本的逻辑将是这样的:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if(readMoreAtIndex == indexPath.row) { return 400; //return as per your requirement } return 100; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //same lines as currently you are doing to setup cell. //important line [cell.btnReadmore setTag:indexPath.row]; [cell.btnReadmore addTarget:self action:@selector(funReadmore:) forControlEvents:UIControlEventTouchUpInside]; if(indexPath.row == readMoreAtIndex) { //setup your cell according to your logic to show expanded view } else { //you are reusing cells, so provide logic to disappear shown expanded view if you want } return cell; } - (IBAction)funReadmore:(id)sender { UIButton *button = (UIButton *)sender; readMoreAtIndex = button.tag; [yourTableView reloadData]; NSLog(@"READ MORE"); }
编辑:教程的链接来实现可扩展/可折叠的tableview。
- 展开/折叠TableView部分
- 适用于iOS的可折叠桌面视图
我发现了另一个基于自动调整表格视图单元格的解决scheme。 而不是更新单元格的高度(硬编码),我们可以更新约束优先级。
fileprivate extension Int { static let rowHeight = 175 } class CellArticleData { var article: Article var isExpanded: Bool init(article: Article, isExpanded: Bool) { self.article = article self.isExpanded = isExpanded } } enum Article: String { case medicine, sport static let allArticles: [Article] = [.medicine, .sport] var title: String { return self.rawValue.capitalized } var description: String { switch self { case .medicine: return "Lorem Ipsum is simply dummy text of the printing and typesetting industry" case .sport: return "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia." } } } class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! var articles: [CellArticleData] = Article.allArticles.map { CellArticleData(article: $0, isExpanded: false) } override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = CGFloat(.rowHeight) } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell let articleData = articles[indexPath.row] cell.setup(articleData: articleData) cell.delegate = self return cell } } extension ViewController: MyCellDelegate { func handleReadMore() { tableView.reloadData() } }
我有一个自定义的类,它代表一个处理协议和约束更新的单元“MyCell”:
protocol MyCellDelegate { func handleReadMore() } class MyCell: UITableViewCell { @IBOutlet weak var topConstraint: NSLayoutConstraint! @IBOutlet weak var bottomConstraint: NSLayoutConstraint! @IBOutlet weak var heightConstraint: NSLayoutConstraint! func setup(articleData: CellArticleData) { self.articleData = articleData titleLabel.text = articleData.article.title descriptionLabel.text = articleData.article.description readMoreLabel.isUserInteractionEnabled = true let readMoreTap = UITapGestureRecognizer(target: self, action: #selector(handleReadMore)) readMoreTap.cancelsTouchesInView = false readMoreLabel.addGestureRecognizer(readMoreTap) updateCellConstraints() } fileprivate func updateCellConstraints() { if let articleData = self.articleData { if !articleData.isExpanded { heightConstraint.priority = 999 topConstraint.priority = 250 bottomConstraint.priority = 250 }else { heightConstraint.priority = 250 topConstraint.priority = 999 bottomConstraint.priority = 999 } } } func handleReadMore() { if let articleData = self.articleData { articleData.isExpanded = !articleData.isExpanded delegate?.handleReadMore(articleData: articleData) } } }
下面是一个显示它的样子的示例: My custom cell MyCell
你需要放置某种标志机制,并在其中pipe理高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
最好的和理想的方法是根据文本计算高度,然后返回高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if(readMore){ return 500; }else{ return 100; } }
如果使用自动布局,则可以使用sizeToFit
方法根据内容手动计算每个标签的大小
我build议您按照以下步骤操作:
在自定义单元格中将可用的内容放在隐藏的UIView容器中。 所以默认情况下是不可见的。
-
当阅读更多的button按下时,处理其绘制tableView的类内的事件触发器,你正在做
funReadmore
处理程序。 -
取单元格的索引并将其添加到
NSMutableArray
对象中。 -
使用以下命令重新载入TableView数据:
[yourTableViewInstance reloadData];
- 在
heightForRowAtIndexPath
委托函数中,像这样写:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 如果(arrayOfExpandedCellIndexes.contains(indexPath.row)) 返回EXTENDED_CELL_HEIGHT; //macros:#define EXTENDED_CELL_HEIGHT 230.0f 其他 返回NORMAL_CELL_HEIGHT; // Macro:#define NORMAL_CELL_HEIGHT 100.0f }
使用这种方法,您可以使用“阅读更多”button处理多个单元格。 如果在你的需求中只有一个单元格可以使用下面的命令展开你的arrayOfExpandedCellIndexes
:
[arrayOfExpandedCellIndexes removeAllObjects];
注意:一旦为单元格调整了高度,不要忘记使隐藏的视图可见。
希望能帮助到你!
我张贴示例代码,将基于button单击展开单元格和文本大小适用于iOS6和iOS 7,这只是示例代码,只是通过这可能会帮助你… 🙂
这只是一个你可以尝试的示例项目
in customCell.h #import <UIKit/UIKit.h> @class CustomCell; @protocol ButtonClickDelegate <NSObject> //custom delegate - (void)whenReadMoreButtonClicked:(CustomCell *)cell;//i am passing the cell itself @end @interface CustomCell : UITableViewCell @property (nonatomic,assign)id<ButtonClickDelegate>delegate; @property (nonatomic,retain)UILabel *mesageLabel; @property (nonatomic,retain)NSString *message; @property (nonatomic,assign)BOOL expand; @end
在customCell.m中
#import "CustomCell.h" @implementation CustomCell @synthesize delegate;//synthesize it @synthesize mesageLabel; @synthesize message; @synthesize expand; - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(5,2, 100, 35)]; [button addTarget:self action:@selector(whenButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; [button setTitle:@"Read More" forState:UIControlStateNormal]; button.backgroundColor = [UIColor greenColor]; self.mesageLabel = [[UILabel alloc]initWithFrame:CGRectMake(0 , 40,0 ,0)]; self.mesageLabel.backgroundColor = [UIColor redColor]; self.mesageLabel.numberOfLines = 100; [self addSubview:self.mesageLabel]; [self addSubview:button]; } return self; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } - (void)whenButtonClicked:(id)sender { if([self.delegate respondsToSelector:@selector(whenReadMoreButtonClicked:)]) { [self.delegate whenReadMoreButtonClicked:self];//delegate to controller } } - (void)layoutSubviews { [super layoutSubviews]; self.mesageLabel.text = self.message; if(self.expand) { CGSize size = [self findMessgeStringHeight]; self.mesageLabel.frame = CGRectMake(0, 40, size.width, size.height); } else { self.mesageLabel.frame = CGRectMake(0, 40, self.bounds.size.width, 100); } } //helper method to find height - (CGSize)findMessgeStringHeight { NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:self.message attributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:17.0f] }]; CGRect rect = [attributedText boundingRectWithSize:(CGSize){225, MAXFLOAT} options:NSStringDrawingUsesLineFragmentOrigin context:nil]; CGSize requiredSize = rect.size; return requiredSize; //finally u return your height } @end
在viewController中
#import "ViewController.h" #import "CustomCell.h" @interface ViewController ( <UITableViewDataSource,UITableViewDelegate,ButtonClickDelegate>//confirm's to delegate { BOOL ButtonClickedForExpand; NSMutableArray *array; } @property (nonatomic,retain)NSIndexPath *previousIndexPath; @property (nonatomic,retain)NSIndexPath *currentIndexPath; @end @implementation ViewController @synthesize previousIndexPath; @synthesize currentIndexPath; - (void)viewDidLoad { [super viewDidLoad]; ButtonClickedForExpand = NO; // Do any additional setup after loading the view, typically from a nib. array = [[NSMutableArray alloc]initWithObjects:@"hello happy coding some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext",@"some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext",@"ello happy coding some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext ello happy coding some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext ello happy coding some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext ello happy coding some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext ello happy coding some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtext some longtextsome longtext some longtext", nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return array.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL"]; if(cell == nil) { cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CELL"]; } if(ButtonClickedForExpand) { if(indexPath.row == currentIndexPath.row) { cell.expand = YES; } else { cell.expand = NO; } } else { cell.expand = NO; } cell.message = [array objectAtIndex:indexPath.row]; cell.delegate = self;//u need to set delegate to self return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGSize size = [self findMessgeStringHeight:[array objectAtIndex:indexPath.row]]; if(ButtonClickedForExpand) { if(indexPath.row == currentIndexPath.row) { return size.height + 30; } else { return 100;//by default } } else { return 100; } } //helper function to return the correct height for your label - (CGSize)findMessgeStringHeight:(NSString *)str { NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:str attributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:17.0f] }]; CGRect rect = [attributedText boundingRectWithSize:(CGSize){225, MAXFLOAT} options:NSStringDrawingUsesLineFragmentOrigin context:nil]; CGSize requiredSize = rect.size; return requiredSize; //finally u return your height } - (void)whenReadMoreButtonClicked:(CustomCell *)cell { ButtonClickedForExpand = YES; self.previousIndexPath = self.currentIndexPath; self.currentIndexPath = [self.tableView indexPathForCell:cell]; [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:self.currentIndexPath] withRowAnimation:UITableViewRowAnimationFade]; if(self.previousIndexPath.row == nil) { return; } else { [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:self.previousIndexPath] withRowAnimation:UITableViewRowAnimationFade]; } } @end
编辑:添加ButtonClickedForExpand
为第一次点击
编辑:2更改if(self.previousIndexPath.row == nil)
在“whenReadMoreButtonClicked”方法的视图控制器
评论如果你没有得到
- TableView高度无法在IOS中resize
- 在tableview中使用UILabel的单元格的dynamic高度
- 如何将投影添加到UITableViewCell的分隔线?
- IOS双击UITableView中的单元格原因项不会滚动
- 在刷行或单击编辑button时,更改UITableViewCell中默认的红色删除button的颜色
- 有没有可能在UITableView中更改字体的types和大小?
- 滚动时在UITableview单元格中维护自定义button的状态
- 从包含url的数组中添加图片到单元格的imageView – iOS Xcode对象C
- 在UITableView和GoogleMap的视图上开始触摸时closures键盘