Naeem
Naeem

Reputation: 789

UISlider Value Automatically assigned while scrolling in UITable View Cell

I am Working on a Program which looks like this:

There is a Table View i that there is a Custom Table View Cell. And there is a UISlider , Label and Button on Custom View Cell

enter image description here

enter image description here

Now the Problem is when i slide the UISlider of Cell : 0 than the UISlider at Cell : 12(or later Cell) is Automatically assigned the Cell:0's UISlider Value(Thanks To ARC..!!).

Now anyone have a solution so that the later cell's UISlider doest change while i change value of upper Cells.

P.S. When i assigned a UiSlider Value at Cell:0 and Scroll Up and Down it is automatically random Cell's UISlider Value is changing.

Google Drive Link of Project : Slider Program

I am Using xCode 5 and iOS SDK 7.

Thanks for Reading.

Edit: cellForRowAtIndexPath Method

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *simpleTableCell = @"Cell";

    CustomeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableCell];


    if (cell == nil) {
        cell = [[CustomeTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableCell];
    }

    NSString *strName = [NSString stringWithFormat:@"Cell : %d",indexPath.row];
//    NSLog(@"strName :%@ , SliderValue : %d",strName , (int)cell.mySlider.value);


    for (int i = 0; i < arrSlider.count; i++) {

        NSString *strTag = [NSString stringWithFormat:@"%@",[[arrSlider objectAtIndex:i]valueForKey:@"tag"]];
        NSString *myIndexPath = [NSString stringWithFormat:@"%d",indexPath.row];

        if([strTag isEqualToString:myIndexPath])
        {
            NSString *strValue = [NSString stringWithFormat:@"%@",[[arrSlider objectAtIndex:i]valueForKey:@"value"]];

            cell.mySlider.value = [strValue floatValue];
            NSLog(@"Tag Value : %@ , value %f", strTag , [strValue floatValue]);

        }

    }

    [cell.btnCell setTitle:strName forState:UIControlStateNormal];

    cell.btnCell.tag = indexPath.row;
    cell.mySlider.tag = indexPath.row;

    [cell.mySlider addTarget:self action:@selector(customSliderValue:) forControlEvents:UIControlEventValueChanged];

    [cell.btnCell addTarget:self action:@selector(customeBtnClicked:) forControlEvents:UIControlEventTouchDown];

    return cell;

}

Upvotes: 2

Views: 1362

Answers (3)

Shankar BS
Shankar BS

Reputation: 8402

Use NSMutableDictionary to hold the values of slider then update it from the cellForRowAtIndexPath method i am posting the changes just make changes in your project

in ViewCOntroller.h file

#import <UIKit/UIKit.h>
#import "CustomeTableViewCell.h"

@interface ViewController : UIViewController <UITableViewDataSource ,UITableViewDelegate,SliderDelegate>//confirms to delegate
{
  //NSArray *tableList;
  UITableView *mytableview;
  NSInteger SliderChangeValue;

}

@property (strong , nonatomic) IBOutlet UIView *tableDemo;
@property (strong , nonatomic) NSMutableArray *arrSlider;
@property (strong,  nonatomic) NSMutableDictionary *sliderDicValues; //add a mutable dictionary 
@property (weak, nonatomic) IBOutlet UITableView *myTableView;//add outlet to tableview

@end

in ViewController.mfile

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize arrSlider;
@synthesize sliderDicValues;

- (void)viewDidLoad  
{
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.
  //    tableList = [NSArray arrayWithObjects:
  //                 @"Cell 1",@"Cell 2",@"Cell 3",@"Cell 4",@"Cell 5",
  //                 @"Cell 6",@"Cell 7",@"Cell 8",@"Cell 9",@"Cell 10",
  //                 @"Cell 11",@"Cell 12",@"Cell 13",@"Cell 14",@"Cell 15",
  //                 @"Cell 16",@"Cell 17",@"Cell 18",@"Cell 19",@"Cell 20",
  //                 nil];

   arrSlider = [[NSMutableArray alloc]init];
   sliderDicValues = [[NSMutableDictionary alloc]init]; //initilise an mutable dictionary
  //[mytableview registerClass:[CustomeTableViewCell class]       forCellReuseIdentifier:@"Cell"];
}

- (void)didReceiveMemoryWarning
{
   [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

 //[tableList count] 
  return 15;
 }

 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   static NSString *simpleTableCell = @"Cell";
   CustomeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableCell];
   if (cell == nil) {
      cell = [[CustomeTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableCell];
   }
   if([self.sliderDicValues objectForKey:[NSString stringWithFormat:@"%d",indexPath.row]]) //check if there is any slided value is present
   {
     NSNumber *value = [self.sliderDicValues objectForKey:[NSString stringWithFormat:@"%d",indexPath.row]];
     [cell.mySlider setValue:value.integerValue]; //set the slider value
     [cell.myCellLabel setText:[NSString stringWithFormat:@"%d",value.integerValue]];//and also label
   }
   else //set to default values
   {
      [cell.mySlider setValue:(NSInteger)0];
      [cell.myCellLabel setText:@"label"];
   }
   //add a single target don't add double target to slider 
   cell.sliderDelegate = self;//set the delegate
   return cell;
/*
 NSString *strName = [NSString stringWithFormat:@"Cell : %d",indexPath.row];
 NSLog(@"strName :%@ , SliderValue : %d",strName , (int)cell.mySlider.value);
 for (int i = 0; i < arrSlider.count; i++) {
     NSString *strTag = [NSString stringWithFormat:@"%@",[[arrSlider objectAtIndex:i]valueForKey:@"tag"]];
     NSString *myIndexPath = [NSString stringWithFormat:@"%d",indexPath.row];

     if([strTag isEqualToString:myIndexPath])
     {
         NSString *strValue = [NSString stringWithFormat:@"%@",[[arrSlider objectAtIndex:i]valueForKey:@"value"]];

         cell.mySlider.value = [strValue floatValue];
         NSLog(@"Tag Value : %@ , value %f", strTag , [strValue floatValue]);    
     }

     if ([strTag isEqual:myIndexPath]) {
         //NSString *strValue = [NSString stringWithFormat:@"%@",[[arrSlider objectAtIndex:i]objectForKey:@"value"]];
         //NSLog(@"%@",strValue);
         NSLog(@"Hello");
         //cell.mySlider.value =
     }
 }
 [cell.btnCell setTitle:strName forState:UIControlStateNormal];
 cell.btnCell.tag = indexPath.row;
 cell.mySlider.tag = indexPath.row;
 [cell.mySlider addTarget:self action:@selector(customSliderValue:) forControlEvents:UIControlEventValueChanged];
 [cell.btnCell addTarget:self action:@selector(customeBtnClicked:) forControlEvents:UIControlEventTouchDown];
 */
}

//delegate method called from custom cell 
- (void)sliderChanged:(CustomeTableViewCell *)cell
{
   NSIndexPath *path = [_myTableView indexPathForCell:cell]; //get the indexpath
   if(path)//check if valid path
   {
      SliderChangeValue = cell.mySlider.value;
      [self.sliderDicValues setObject:[NSNumber numberWithInt:SliderChangeValue] forKey:[NSString stringWithFormat:@"%d",path.row]]; //set the value in the dictionary later used in the cellForRowAtIndexPath method
   }
   //     SliderChangeValue = (int)sender.value;
        NSLog(@"%d",SliderChangeValue);
}


 //dont use it
 -(void)customSliderValue:(UISlider *)sender{

 //    NSString *value =[NSString stringWithFormat:@"%d" ,(int)sender.value];
 //    NSString *tag = [NSString stringWithFormat:@"%d", (int)sender.tag];
 //    
 //    NSLog(@"%@ %@",value , tag);
 //    
 //    [self.dicSilder setObject:value forKey:@"value"];
 //    [self.dicSilder setObject:tag forKey:@"tag"];
 //    
 //    [self.arrSlider addObject:self.dicSilder]; 
 //    NSLog(@"%@",self.arrSlider);


    SliderChangeValue = (int)sender.value;

    NSLog(@"%d",SliderChangeValue);

 }

 //this is also put a delegate from the cell like slider , just add the another method in the protocol and perform action, if u don't get just comment i will update the code and u hav t modify this method according to your requirement
 -(void)customeBtnClicked:(UIButton *)sender
 { 
    NSString *value =[NSString stringWithFormat:@"%d" ,SliderChangeValue];
    NSString *tag = [NSString stringWithFormat:@"%d", sender.tag];

    //NSLog(@"%@ %@",value,tag);
    NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
    [dic setObject:value forKey:@"value"];
    [dic setObject:tag forKey:@"tag"];

    //NSLog(@"%@",dic);

    [arrSlider addObject:dic];


     NSLog(@"%@",arrSlider);

     NSString *sliderTagAtIndexPath = @"";
    //NSString *sliderValueAtindexPath = @"";

     for (int i = 0; i < arrSlider.count; i++) {

     NSString *strTag = [NSString stringWithFormat:@"%@",[[arrSlider objectAtIndex:i]valueForKey:@"tag"]];

      if([strTag isEqualToString:tag])
      {       
        //NSString *strValue = [NSString stringWithFormat:@"%@",[[arrSlider objectAtIndex:i]valueForKey:@"value"]];

        sliderTagAtIndexPath = strTag;
        //sliderValueAtindexPath = strValue; 
     }
    }
    UIAlertView *myAlertView = [[UIAlertView alloc]initWithTitle:@"Clicked"
                                                     message:[NSString stringWithFormat:@"Cell : %@ Value: %d", sliderTagAtIndexPath ,SliderChangeValue]
                            //message:[NSString stringWithFormat:@"Cell : %@ Value: %@", sliderTagAtIndexPath ,sliderValueAtindexPath]
                                                    delegate:self
                                           cancelButtonTitle:@"OK"
                                           otherButtonTitles:nil];

    [myAlertView show];

}
@end

in CustomeTableViewCell.h file

#import <UIKit/UIKit.h>
//add a custom delegate
@protocol SliderDelegate<NSObject>
- (void)sliderChanged:(id)self;
@end

@interface CustomeTableViewCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UILabel *myCellLabel;
@property (weak, nonatomic) IBOutlet UISlider *mySlider;
@property (weak, nonatomic) IBOutlet UIButton *btnCell;
@property (weak, nonatomic) id <SliderDelegate>sliderDelegate;

 - (IBAction)sliderValuechanged:(UISlider *)sender;

@end

in CustomeTableViewCell.m file

 #import "CustomeTableViewCell.h"

 @implementation CustomeTableViewCell

 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
 {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
     // Initialization code
    }
    return self;
}

- (void)awakeFromNib
{
   // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (IBAction)sliderValuechanged:(UISlider *)sender
{
   self.myCellLabel.text = [NSString stringWithFormat:@"%d",(NSInteger)sender.value];
   //call the custom delegate each time when slider is slided
   if([_sliderDelegate respondsToSelector:@selector(sliderChanged:)])
   {
       [_sliderDelegate sliderChanged:self]; //passing the entire cell itself
   } 
}
@end

Hope this helps u .. :)

Upvotes: 3

Chetan
Chetan

Reputation: 2124

Try this code it works for me :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{


   NSString *identifier = [NSString stringWithFormat:@"%d",indexPath.row];
    CustomeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (!cell) {
        cell = [[CustomeTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
// Write your rest code here
return cell;


}

Upvotes: 0

Kumar KL
Kumar KL

Reputation: 15335

You don't need to check(set) all the datasource for a Cell , I mean, No need of for loop inside the cellForRowAtIndexPath. just remove it and will work fine .

Upvotes: 0

Related Questions