views:

79

answers:

3

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 ?

A: 

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
I'm not sure .......Because I just reference the answer and directly copy into my code....
WebberLai
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
that's not my answer...just someone tell me this can be work...so I copy his answer.
WebberLai
WebberLai
so, that answer doesn't work. Why do you need to get the indexPath? For what purpose
vodkhang
I think you need to do theSwitch.superView.superView.superView , 3 times, try with that
vodkhang
sorry,Vodkhang...can you write a sample code for me ?I really don't understand how to do...I stuck here almost one day...
WebberLai
The sample code that I suggest is : theSwitch.superView.superView.superView
vodkhang
Cool It won't crash But no return back "NSLog(@"You Switch On the NodeID:%i ",indexPath.row);" I will try some breakpoint
WebberLai
What is the output of the NSLog, anything?
vodkhang
I click the switch ,Nothing return but the image change function is fine
WebberLai
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
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.
WebberLai
reason :Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewControllerWrapperView indexPathForCell:]and "Program received signal: “SIGABRT”."
WebberLai
uhm, so it is not correct, this approach to call superview is just wrong:(
vodkhang
what if I send u my code ?can you check for me ?
WebberLai
it is ok, you can send me your file, I don't have XCode here but will try to do code inspection for you. `[email protected]`
vodkhang
THANK YOU ! I'll send it now
WebberLai
yes You give a right answer :UITableViewCell *cell = (UITableViewCell *)theSwitch.superview; ->UITableViewCell *cell = (UITableViewCell *)theSwitch.superview.superView;
WebberLai
A: 

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 svv
but still don't know to get which switch I click ?
WebberLai
yourSwitch.on is correct, it is a property
vodkhang
A: 

I have found the answer! theSwitch.superview actually returns the contentView inside UITableViewCell. So you should change to: UITableViewCell *cell = (UITableViewCell *)theSwitch.superview.superview;

NQVU2003