1

Here is my old question Link

I ask a question before,But I put the answer in my code It can compiler without error

But when I click the switch ,the program crash

I just want to click the switch ,than return which row I click

Here is my code

First I create a LightTableViewController.h/.m

Than I create LightCell0.h/.m

in LightCell0.h

@interface LightCell0 : UITableViewCell { 
 UILabel     *lightLocation;
 UIImageView *lightImageView;
 UISwitch    *lightSwitch;   
}

@property(nonatomic,retain) UILabel *lightLocation;
@property(nonatomic,retain) UIImageView *lightImageView;
@property(nonatomic,retain) UISwitch *lightSwitch;

- (void)switchlightswitch:(id)sender;

I need each cell will be an image ,Textlabel ,switch inside

In LightCell.m

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
 if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
  lightLocation = [[UILabel alloc]init];
  lightLocation.textAlignment = UITextAlignmentLeft;
  lightLocation.font = [UIFont boldSystemFontOfSize:20];
  lightLocation.backgroundColor = [UIColor blackColor];
  lightLocation.textColor =[UIColor whiteColor];

  lightImageView = [[UIImageView alloc]init];

  lightSwitch = [[UISwitch alloc]init];

  [self.contentView addSubview:lightLocation];
  [self.contentView addSubview:lightImageView];
  [self.contentView addSubview:lightSwitch];

  [lightSwitch addTarget:self action:@selector(switchlightswitch:) forControlEvents:UIControlEventValueChanged];

  // Initialization code

    }
    return self;
}

- (void)switchlightswitch:(id)sender{

 if (lightSwitch.on){
  lightImageView.image = [UIImage imageNamed:@"lightOn.png"];
 }
 else {
  lightImageView.image = [UIImage imageNamed:@"lightOff.png"]; 

} }

- (void)layoutSubviews {

 [super layoutSubviews];
 CGRect contentRect = self.contentView.bounds;
 CGFloat boundsX = contentRect.origin.x;
 CGRect frame;
 frame = CGRectMake(boundsX+10 ,0, 44, 44);
 lightImageView.frame = frame;
 frame = CGRectMake(boundsX+60 ,3, 150, 44);
 lightLocation.frame = frame;
 frame = CGRectMake(boundsX+220, 10,0,0);
 lightSwitch.frame = frame ;

}

So far,the program can response when i change the switch status ,it will also change the image.

but if I put this code in ,i can compiler ,than crash if I touch any switch

[lightSwitch addTarget:self action:@selector(switchToggled:) forControlEvents:UIControlEventValueChanged];

and give a void

- (void)switchToggled:(id)sender {
 UISwitch *theSwitch = (UISwitch *)sender;
    UITableViewCell *cell = (UITableViewCell *)theSwitch.superview;
    UITableView *tableView = (UITableView *)cell.superview;
    NSIndexPath *indexPath = [tableView indexPathForCell:cell];
    if(theSwitch.on) {
  NSLog(@"You Switch On the NodeID:%i ",indexPath.row);
    }
    else {
  NSLog(@"You Switch Off the NodeID:%i ",indexPath.row);
    }
}

the crash message is "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[LightCell0 indexPathForCell:]: unrecognized selector sent to instance"

does anyone knows what's going on with my code ?

Community
  • 1
  • 1
Webber Lai
  • 2,014
  • 5
  • 35
  • 66

3 Answers3

1

From the error message, I suspect your cast is wrong:

UITableViewCell *cell = (UITableViewCell *)theSwitch.superview;
UITableView *tableView = (UITableView *)cell.superview;

Are you sure that the superview of theSwitch is a UITableViewCell and the super view of the cell is the UITableView. The crash tell you that the tableView object that you respect is a LightCell0 object

vodkhang
  • 18,639
  • 11
  • 76
  • 110
  • I'm not sure .......Because I just reference the answer and directly copy into my code.... – Webber Lai Sep 15 '10 at 08:31
  • Vodkhang is correct, your logic/design is wrong at some point. The 'superview' of the 'superview' of the switch is your cell and not the tableview as you expect – Liam Sep 15 '10 at 08:37
  • that's not my answer...just someone tell me this can be work...so I copy his answer. – Webber Lai Sep 15 '10 at 08:46
  • so, that answer doesn't work. Why do you need to get the indexPath? For what purpose – vodkhang Sep 15 '10 at 09:19
  • I think you need to do theSwitch.superView.superView.superView , 3 times, try with that – vodkhang Sep 15 '10 at 09:33
  • sorry,Vodkhang...can you write a sample code for me ?I really don't understand how to do...I stuck here almost one day... – Webber Lai Sep 15 '10 at 10:13
  • The sample code that I suggest is : theSwitch.superView.superView.superView – vodkhang Sep 15 '10 at 10:15
  • Cool It won't crash But no return back "NSLog(@"You Switch On the NodeID:%i ",indexPath.row);" I will try some breakpoint – Webber Lai Sep 15 '10 at 10:43
  • What is the output of the NSLog, anything? – vodkhang Sep 15 '10 at 11:45
  • I click the switch ,Nothing return but the image change function is fine – Webber Lai Sep 15 '10 at 11:55
  • You mean nothing in the console, did you set breakpoint in ` if(theSwitch.on) { NSLog(@"You Switch On the NodeID:%i ",indexPath.row); } else { NSLog(@"You Switch Off the NodeID:%i ",indexPath.row); }`. Does the runtime call either if or else? – vodkhang Sep 15 '10 at 12:08
  • Sorry I make a mistake,I forget to remove the mark,The void was not call,so the program wont crash,after I remove the mark,the program crash again. – Webber Lai Sep 15 '10 at 12:27
  • reason :Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewControllerWrapperView indexPathForCell:]and "Program received signal: “SIGABRT”." – Webber Lai Sep 15 '10 at 12:28
  • uhm, so it is not correct, this approach to call superview is just wrong:( – vodkhang Sep 15 '10 at 12:48
  • it is ok, you can send me your file, I don't have XCode here but will try to do code inspection for you. `vodkhang@gmail.com` – vodkhang Sep 15 '10 at 12:57
  • yes You give a right answer :UITableViewCell *cell = (UITableViewCell *)theSwitch.superview; ->UITableViewCell *cell = (UITableViewCell *)theSwitch.superview.superView; – Webber Lai Sep 15 '10 at 15:49
0

For getting the status of the switch, you are using "yourSwitch.on", which I don't think is correct. Chang it to [yourSwitch isOn] and test your app. I see 2 statements in your code where you are checking the state of a switch. Change them and try.

Satyam
  • 15,493
  • 31
  • 131
  • 244
0

I have found the answer! theSwitch.superview actually returns the contentView inside UITableViewCell. So you should change to:

UITableViewCell *cell = (UITableViewCell *)theSwitch.superview.superview;
Pragnesh Chauhan
  • 8,363
  • 9
  • 42
  • 53