Ios 在tableview单元格中动态调整子视图的大小

Ios 在tableview单元格中动态调整子视图的大小,ios,xcode,uitableview,addsubview,Ios,Xcode,Uitableview,Addsubview,关于在tableView单元格中添加子视图,我有一个较小的问题 我的单元格背景是动态的百分比计数 我得到了正确的百分比,我可以完美地设置背景,但是当我添加一个新条目时。。都搞砸了 我得到的新条目是完美的,但之前的单元格即使在我调整大小后仍然保持不变 神奇的是当我停下来,以完美的方式建造它 请帮帮我 我使用以下代码来实现这一点 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSInd

关于在tableView单元格中添加子视图,我有一个较小的问题

我的单元格背景是动态的百分比计数

我得到了正确的百分比,我可以完美地设置背景,但是当我添加一个新条目时。。都搞砸了

我得到的新条目是完美的,但之前的单元格即使在我调整大小后仍然保持不变

神奇的是当我停下来,以完美的方式建造它

请帮帮我

我使用以下代码来实现这一点

-(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];
}