Ios 在tableview单元格中动态调整子视图的大小
关于在tableView单元格中添加子视图,我有一个较小的问题 我的单元格背景是动态的百分比计数 我得到了正确的百分比,我可以完美地设置背景,但是当我添加一个新条目时。。都搞砸了 我得到的新条目是完美的,但之前的单元格即使在我调整大小后仍然保持不变 神奇的是当我停下来,以完美的方式建造它 请帮帮我 我使用以下代码来实现这一点Ios 在tableview单元格中动态调整子视图的大小,ios,xcode,uitableview,addsubview,Ios,Xcode,Uitableview,Addsubview,关于在tableView单元格中添加子视图,我有一个较小的问题 我的单元格背景是动态的百分比计数 我得到了正确的百分比,我可以完美地设置背景,但是当我添加一个新条目时。。都搞砸了 我得到的新条目是完美的,但之前的单元格即使在我调整大小后仍然保持不变 神奇的是当我停下来,以完美的方式建造它 请帮帮我 我使用以下代码来实现这一点 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSInd
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// Dequeue the cell.
speedoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"speedoCell" forIndexPath:indexPath];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
CGRect rect = cell.frame;
NSLog(@"Cell width = %f",rect.size.width);
float cell_width=rect.size.width;
float per;
float viewSize=0.0;
if (self.recent_calls.count == 0) {
cell.title.text =@"No records";
cell.desc.text =@"";
}
else{
NSInteger indexOfFirstname = [self.dbManager.arrColumnNames indexOfObject:@"ex_category"];
NSInteger indexOfSecondname = [self.dbManager.arrColumnNames indexOfObject:@"totle"];
NSString *totle_cat=[NSString stringWithFormat:@"%@", [[self.recent_calls objectAtIndex:indexPath.row] objectAtIndex:indexOfSecondname]];
int x=[totle_cat intValue];
NSLog(@"%d--yoyoyoyoyoyoyoyoyoyo--%d",x,amount_totle);
float result=0;
result=((float)x/(float)amount_totle)*100;
// cell_width is static = 343.0 ..... result is percentage we found
viewSize=(cell_width*result)/100;
NSLog(@"%f----------",viewSize);
UIView *view,*view1;
view=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
view1=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
view1.frame=CGRectMake(5, 5, cell.frame.size.width-10, cell.frame.size.height-3);
[view1.layer setCornerRadius:8.0f];
[view1.layer setMasksToBounds:YES];
[view1.layer setBorderWidth:0.5f ];
CGRect frame = view.frame;
frame.size.width = viewSize;
frame.size.height=cell.frame.size.height-3;
view.frame = frame;
NSLog(@"%f",view.frame.size.width);
[view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"road_panorama1.jpg"]]];
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *visualEffectView;
visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
visualEffectView.frame = CGRectMake(0, 0, viewSize, cell.frame.size.height-3);
[view addSubview:visualEffectView];
[view1 setBackgroundColor:[UIColor whiteColor]];
[view1 insertSubview:view atIndex:0];
[cell.contentView insertSubview:view1 atIndex:0];
UIImage *image;
if ([category isEqualToString:@"Travel"]) {
image=[UIImage imageNamed:@"taxi13.png"];
}
else if ([category isEqualToString:@"Food"]) {
image=[UIImage imageNamed:@"fastfood6.png"];
}
else if ([category isEqualToString:@"Medical"]) {
image=[UIImage imageNamed:@"stethoscope11.png"];
}
else if ([category isEqualToString:@"Shopping"]) {
image=[UIImage imageNamed:@"shopping-cart13.png"];
}
else{
image=[UIImage imageNamed:@"question-mark2.png"];
}
[cell.img setImage:image];
}
return cell;
}
从第二视图控制器添加条目
NSString *query= [NSString stringWithFormat:@"insert into ex_man_last (ex_title,ex_amount,ex_description,ex_date,ex_category,ex_upload_date,ex_image,ex_my) values ('%@','%@','%@','%@','%@','%@','%@','%@')",_ex_title.text,_ex_amount.text,_ex_description.text,_ex_date.text,_ex_category.text,datestring,imageName,my ];
// Execute the query.
[self.dbManager executeQuery:query];
调用该方法以从视图中的db获取更新的条目将出现method
NSString *query =[NSString stringWithFormat:@"SELECT *,sum(ex_amount) as totle FROM ex_man_last where ex_my='%@' GROUP BY ex_category ",query_date];
if (self.recent_calls != nil ) {
self.recent_calls = nil;
}
self.recent_calls = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
NSLog(@"--->%@",_ex_main);
NSLog(@"%lu",(unsigned long)[self.recent_calls count]);
NSInteger indexOfSecondname = [self.dbManager.arrColumnNames indexOfObject:@"totle"];
for (int i=0; i<[self.recent_calls count]; i++) {
NSString *amount=[[self.recent_calls objectAtIndex:i] objectAtIndex:indexOfSecondname] ;
amount_totle=amount_totle+[amount intValue];
}
NSString*query=[NSString stringWithFormat:@“SELECT*,sum(EXU amount)为EXU MANU last的总计,其中EXU my='%@'按EXU类别分组”,query_date];
if(self.recent_calls!=nil){
self.recent_calls=nil;
}
self.recent_calls=[[NSArray alloc]initWithArray:[self.dbManager loadDataFromDB:query]];
NSLog(@“-->%@”,前主数据);
NSLog(@“%lu”,(无符号长)[self.recent_calls count]);
NSInteger indexOfSecondname=[self.dbManager.arrColumnNames indexOfObject:@“totle”];
对于(int i=0;i当您使用speedoCell*cell=[tableView dequeueReusableCellWithIdentifier:@“speedoCell”forindexath:indexath]使用可重用单元时;
因此,一旦分配了单元,它将被一次又一次地重用
考虑一个案例,第一次创建包含两个单元格的表格,如屏幕截图1所示,医疗和旅行分别占80%和20%。因此,您创建了模糊视图,并将其添加到白色视图上,最后在单元格内容视图的第0个索引上插入了view1(具有包含模糊效果的白色背景的视图)
上述案例非常有效
再一次,你插入新的条目(细胞)食物,所有的事情都搞砸了!!!
这里的问题是,由于之前为索引0和1创建了两个单元格,因此它们被重用,这次数据被更改,因此您计算了模糊和白色区域,创建了视图,并再次插入索引0处单元格的contentView,这就是问题所在
已在索引处插入的视图将可见,而不考虑在superview上的同一索引处添加的其他视图
若要解决此问题,如果重新使用单元,则必须检查重新使用单元是否包含具有模糊效果的白色背景视图,然后必须先将其删除,重新计算模糊和白色区域,然后再次在单元contentView的索引0处插入视图1
这一次,由于单元被重用,因此首先我们从单元的内容视图中删除索引0处已插入的视图,再次创建白色+模糊视图,并在单元内容视图的第0个索引上插入新创建的视图,并且始终会显示新创建的视图(在一个视图存在且较早的视图被删除时).好的,让我们试试这个
为什么要在方法cellforrowatinexpath
中做每件事,它的工作是为tableview返回单元格,而不是处理单元格内的所有子视图
单元格是处理其内部所有内容的单元格。它包含包含视图组件的内容视图,因此我们不允许单元格处理其视图组件。为此,我们需要将一些信息传递给它,例如,在您的案例中,百分比和标签文本以及u显示的图像,其余部分留给单元格。此如果你正在根据(MVC)模式修改某些东西或添加新组件,我也会使用完整的功能
我不会把所有的事情都集中在你的问题上,在你的cellforrowatinedexpath
中,你每次都会不断地添加新的视图,即使重复使用的单元格也是如此。只要删除所有视图处理代码(这将在自定义单元格中使用)
如果你只想创建一个新项目并进行尝试,我真的在这里尝试了你的代码,我认为它工作得很好,所以让我们尝试一个新项目,以便你清楚地理解,最后我还将添加gif文件以显示结果如何
首先用子类UITableViewCell
创建一个新文件,并给它一个名称,我给它命名为CustomCell
在CustomCell.h
文件中
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface CustomCell : UITableViewCell
//creating the properties for all view components and also for percentage value that we need for calculating of width
//i took your code hear
@property (nonatomic, assign) CGFloat percentage;
@property (nonatomic, assign) CGFloat viewWidth;
@property (nonatomic, strong) UIView *view;
@property (nonatomic, strong) UIView *view1;
@property (nonatomic, strong) UIBlurEffect *blurEffect ;
@property (nonatomic, strong) UIVisualEffectView *visualEffectView;
@property (nonatomic, strong) UILabel *percentageLabel ;
@end
#import "CustomCell.h"
@implementation CustomCell
//we are using this to create new cell just override it and call super
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self)
{
[self initiliseViewComponents]; //hear we are adding views to cell
}
return self;
}
- (void)setPercentage:(CGFloat)percentage
{
float result=0;
result=((float)percentage/(float)100)*100;
_percentage = result;
_viewWidth = result*343 / 100;
_percentageLabel.text = [NSString stringWithFormat:@"%d",(int)_percentage]; //to show the percentage
}
//at this point we don't no the size of cell,
//same what u are doing in your project just initialising and add it to cell's content view
- (void)initiliseViewComponents
{
_view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
_view1 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
_blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
_visualEffectView = [[UIVisualEffectView alloc] initWithEffect:_blurEffect];
_percentageLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
[_view addSubview:_visualEffectView];
[_view1 setBackgroundColor:[UIColor whiteColor]];
[_view1 insertSubview:_view atIndex:0];
[self.contentView insertSubview:_view1 atIndex:0];
[self.contentView addSubview:_percentageLabel];
}
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
//in this method just set frames for your subviews this method will be called automatically
//dont change the cell's frame just the subviews frame
- (void)layoutSubviews
{
_percentageLabel.frame = CGRectMake(self.contentView.bounds.size.width - 50, self.contentView.bounds.origin.y + 10, 50, 50);
CGRect cellFrame = self.contentView.frame;
cellFrame.origin.x += 5;
cellFrame.origin.y += 5;
cellFrame.size.width -= 10;
cellFrame.size.height -= 3;
_view1.frame=cellFrame;
[_view1.layer setCornerRadius:8.0f];
[_view1.layer setMasksToBounds:YES];
[_view1.layer setBorderWidth:0.5f ];
// [_view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"images2.jpg"]]];
[_view setBackgroundColor:[UIColor redColor]];
self.backgroundColor = [UIColor clearColor];
CGRect frame = _view.frame;
frame.size.width = _viewWidth;
frame.size.height = self.frame.size.height-3;
_view.frame = frame;
_visualEffectView.frame = CGRectMake(0, 0, _viewWidth, frame.size.height);
NSLog(@"%f",_view.frame.size.width);
[super layoutSubviews]; //finally call super
}
@end
然后来到主控制器
在主视图控制器中,
添加一个tableview并为其设置一个插座
//in ViewController.h
@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *aTableView;
@property (strong,nonatomic) NSMutableArray *aMutableArray; //to holde percentages
所以点击run按钮,结果如下所示
很抱歉,我不得不压缩gif图像质量有点低蓝色按钮用于将新单元格添加到tableview,而标签不是必需的
希望这有助于u重新启动,因为行的单元格代码正确,如何向表视图中添加新条目,您是否确保重新加载表视图。您没有考虑单元格重用。当您滚动并重用单元格时,您将向已具有v的单元格添加view1iew1.能否发布cellForRowAtIndexPath的完整实现?以及添加新条目和重新加载表格的方式?我确实在ViewDidDisplay方法中重新加载表格?确定我发布完成问题解决了吗?只需将标签分配给view1,然后将其作为[view1 setTag:view_tag]插入单元格的内容视图中即可;然后在执行[cell.contentView insertSubview:view1 atIndex:0]时添加它;当您以身份访问单元格时,speedoCell*cell=[tableView dequeueReusableCellWithIdentifier:@“speedoCell”forindexath:indexath];然后检查单元格的内容视图是否包含标记视图或notUIView*view1=[cell.contentView-viewWithTag:VIEW_-TAG];if(view1)[view1-removeFromSuperview];
- (void)viewDidLoad
{
[super viewDidLoad];
_aMutableArray = [[NSMutableArray alloc]initWithObjects:@(20),@(30),@(50), nil]; //initially it has 3 values we will add some more dynamically
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _aMutableArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL"];
if(cell == nil)
{
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CELL"];
}
cell.percentage = [[_aMutableArray objectAtIndex:indexPath.row] floatValue];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60.0f;
}
//this action method to add new cell dynamically at the top of the tableview
- (IBAction)addButtonAction:(id)sender
{
CGFloat nextPerent = arc4random_uniform(80) % 100; //i took some random percentage values
[_aMutableArray insertObject:[NSNumber numberWithFloat:nextPerent] atIndex:0];
[_aTableView reloadData];
}