我有单独的自定义UITableViewCell
用于显示数据(这些数据来自服务器JSON响应)。在每个UITableViewCell
我有按钮阅读更多。如果用户点击阅读更多按钮我想要以编程方式添加UILabel
以显示来自server的其他信息。但最初我设置了UITableViewCell
高度,所以在点击了更多按钮后我无法看到额外的信息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];
}
答案 0 :(得分:25)
首先采取bool
& int
变量。
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;
}
希望它对你有用。
答案 1 :(得分:4)
将int readMoreAtIndex;
作为您的类变量。在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的教程的链接。
答案 2 :(得分:2)
我找到了基于self-sizing表格视图单元格的另一种解决方案。我们可以更新约束优先级,而不是更新单元格的高度(硬编码)。
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
答案 3 :(得分:1)
你需要放置某种旗帜机制并在
中管理高度 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
最好和理想的方法是根据文字计算高度,然后返回高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(readMore){
return 500;
}else{
return 100;
}
}
如果您使用自动布局,则可以使用sizeToFit
方法
答案 4 :(得分:1)
我发布了基于按钮点击扩展单元格的示例代码,文本大小适用于iOS6和iOS 7,这只是示例代码,只需通过这个可能有助于你...:)< / p>
这只是您可以尝试的示例项目
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
#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在视图控制器的“whenReadMoreButtonClicked”方法中更改了if(self.previousIndexPath.row == nil)
如果你没有得到评论
答案 5 :(得分:1)
我建议您按照以下步骤操作:
在自定义单元格中,您可以使用的内容,将其放入隐藏的UIView容器中。因此默认情况下不可见。
当按下更多按钮时,在绘制tableView的类中处理它的事件触发器funReadmore
处理程序。
获取单元格的索引并在NSMutableArray
对象中管理/添加。
使用以下方式重新加载TableView数据:
[yourTableViewInstance reloadData];
heightForRowAtIndexPath
委托函数中,将其写成:- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if(arrayOfExpandedCellIndexes.contains(indexPath.row)) return EXTENDED_CELL_HEIGHT; // Macro : #define EXTENDED_CELL_HEIGHT 230.0f else return NORMAL_CELL_HEIGHT; // Macro : #define NORMAL_CELL_HEIGHT 100.0f }
使用这种方式,您可以按下“阅读更多”按钮处理多个单元格。如果在您的要求中,只有一个单元格可以使用以下内容展开arrayOfExpandedCellIndexes
:
[arrayOfExpandedCellIndexes removeAllObjects];
注意:为细胞调整高度后,不要忘记隐藏视图。
希望它有所帮助!