2012-10-29 10 views
5

Ho un UITableView con UISwitchs su di essi.Selezionare la riga di UITableView quando si fa clic su UISwitch

TableView

Quando l'interruttore viene commutato Voglio correre una funzione. La funzione registra solo se l'interruttore è acceso o spento e la riga su cui è stato cambiato l'interruttore. Il problema che sto avendo è che quando clicco sull'interruttore non registra la riga corretta a meno che non abbia fatto clic su quella riga prima di fare clic sull'interruttore.

Credo che il mio problema è che facendo clic sull'interruttore non si seleziona la riga. Come posso fare in modo che selezioni la riga o posso aggiungere l'ID all'interruttore?

Quindi l'ID dell'interruttore "1" è "ON".

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    static NSString *CellIdentifier = @"POICell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 


    //set the cell text to the catName 
    cell.textLabel.text = [self.catNames objectAtIndex:[indexPath row]]; 
    //add switch 
    cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero]; 
    cell.accessoryView = switchView; 
    [switchView setOn:YES animated:NO]; 

    [switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged]; 
    // Configure the cell... 

    return cell; 
} 

    - (void) switchChanged:(id)sender { 
      NSString *StrCatID =[[NSString alloc]init]; 
      StrCatID = [self.catIDs objectAtIndex:[self.inputTableView indexPathForSelectedRow].row]; 
      UISwitch* switchControl = sender; 
      NSLog(@"The switch for item %@ is %@",StrCatID, switchControl.on ? @"ON" : @"OFF"); 
     } 

risposta

10

Per trovare la cella che contiene l'interruttore

UISwitch *switchInCell = (UISwitch *)sender; 
UITableViewCell * cell = (UITableViewCell*) swithInCell.superview; 

Per trovare l'indexpath di quella cella

NSIndexPath * indexpath = [myTableView indexPathForCell:cell] 

Nella tua case

- (void) switchChanged:(id)sender { 

     UISwitch *switchInCell = (UISwitch *)sender; 
     UITableViewCell * cell = (UITableViewCell*) swithInCell.superview; 
     NSIndexPath * indexpath = [myTableView indexPathForCell:cell] 
     NSString *strCatID =[[NSString alloc]init]; 
     strCatID = [self.catIDs objectAtIndex:indexpath]; 
     NSLog(@"The switch for item %@ is %@",StrCatID, switchInCell.on ? @"ON" : @"OFF"); 
     } 
+3

In iOS7, la superview sarà UITableViewCellContentView, che è racchiusa in UITableViewCellScrollView. È possibile invece ottenere il percorso dell'indice della cella utilizzando quanto segue: CGPoint switchPositionPoint = [sender convertPoint: CGPointZero toView: [self tableView]]; NSIndexPath * indexPath = [[self tableView] indexPathForRowAtPoint: switchPositionPoint]; – NSDestr0yer

1

penso che il problema è che si utilizza dequeueReusableCellWithIdentifier, e tutto il vostro cellulare ha lo stesso ID.

+0

Se utilizzo [self.inputTableView indexPathForSelectedRow] .row Id mi dà la riga selezionata. – Will

1

Un modo migliore per farlo è di determinare quale cella il mittente è in.

- (UITableViewCell *)findCellForView:(UIView *)view 
{ 
    for (; view != nil; view = view.superview) 
     if ([view isKindOfClass:[UITableViewCell class]]) 
      return view; 
    return nil; 
} 

Una volta che avete questo metodo. quindi è una questione di sostituire [self.inputTableView indexPathForSelectedRow] con

UITableViewCell *cell = [self findCellForView:sender]; 
NSIndexPath *indexPath = [self.inputTableView indexPathForCell:cell]; 
9

è necessario impostare il IndexPath.row come un tag ad ogni Switch in cellForRowAtIndexPath Metodo

switchView.tag= indexPath.row; 

E quando il cambiamento del valore interruttore .you'll ottenere il numero di riga

- (void) switchChanged:(UISwitch *)sender { 
    int rowIndex =[sender tag]; 
    //rowIndex you may use it further as you wanted. 

}

+0

Penso che questo sia di gran lunga l'approccio migliore. Gli altri approcci per osservare la gerarchia delle viste e ancor peggio, traducendo un punto in una vista, si sentono come un hacker e come un sacco di lavoro. L'unico problema che potresti incontrare con questa soluzione è se hai più sezioni, ma ciò può essere risolto facendo in modo che il tag codifichi sia la sezione che la riga. Qualcosa del genere: switchView.tag = indexPath.section * 1000 + indexPath.row; –

4

Ho dovuto fare il doppio mySwitch.superview.superview per ottenere la cella corretta.

Ecco un esempio

- (void)switchToggle:(UISwitch *)mySwitch 
{ 

UITableViewCell *cell = (UITableViewCell *)mySwitch.superview.superview; 
NSIndexPath *indexpath = [self.tableView indexPathForCell:cell]; 
NSLog(@"toggle section %d rowID %d", indexpath.section, indexpath.row); 

} 
-1
#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate> 
@property (retain, nonatomic) IBOutlet UITableView *tableview; 

@end 


@interface ViewController() 
{ 
    NSMutableArray *arr; 
    UITableViewCell* aCell; 
    UISwitch *myswitch; 
} 


#import "ViewController.h" 

@interface ViewController() 
{ 
    NSMutableArray *arr; 
    UITableViewCell* aCell; 
    UISwitch *myswitch; 
} 

@end 

@implementation ViewController 
@synthesize tableview; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    arr = [[NSMutableArray alloc]initWithObjects:@"1",@"2",@"3",@"4",@"5", nil]; 
    // Do any additional setup after loading the view, typically from a nib. 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; 
{ 
    return [arr count]; 
} 



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; 
{ 
    aCell = [tableview dequeueReusableCellWithIdentifier:@"SwitchCell"]; 

    if(aCell == nil) 
     { 
     aCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SwitchCell"]; 
     aCell.textLabel.text = [arr objectAtIndex:indexPath.row]; 
     myswitch = [[UISwitch alloc]initWithFrame:CGRectZero]; 
     aCell.accessoryView = myswitch; 
     [myswitch setOn:YES animated:YES]; 

     } 
    switch (indexPath.row) 

    { 
     case 0: 
     { 
      [myswitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged]; 

     } 
      break; 
     case 1: 
     { 
      [myswitch addTarget:self action:@selector(switchChanged1:) forControlEvents:UIControlEventValueChanged]; 
     } 
      break; 

    } 
    return aCell; 
} 

- (void) switchChanged:(id)sender { 
    UISwitch *aswitch = sender; 

    if (aswitch.on==YES) { 
     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"hello" message:@"okfine" delegate:self cancelButtonTitle:@"done" otherButtonTitles:nil, nil]; 
     [alert show]; 
    } 
    else 
    { 
     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"no1" message:@"notfine" delegate:self cancelButtonTitle:@"Returnback" otherButtonTitles:nil, nil]; 
     [alert show]; 

    } 

} 
- (void) switchChanged1:(id)sender { 
    UISwitch *aswitch1 = sender; 

    if (aswitch1.on==YES) { 
     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"second" message:@"okfine" delegate:self cancelButtonTitle:@"done" otherButtonTitles:nil, nil]; 
     [alert show]; 
    } 
    else 
    { 
     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"no2" message:@"notfine" delegate:self cancelButtonTitle:@"Returnback" otherButtonTitles:nil, nil]; 
     [alert show]; 

    } 
    } 


- (void)dealloc { 
    [tableview release]; 
    [super dealloc]; 
} 
@end 
+0

Astenersi dal pubblicare solo risposte in codice. Si prega di aggiungere una spiegazione ad esso. – Sudipta

+0

Aggiungere un mucchio di codice a un post di un anno senza una spiegazione non è molto utile. Per favore, spiega così altri che vedere questo potrebbe essere aiutato – Will

8

È possibile recuperare il NSIndexPath per l'UISwitch che è stata modificata nel Tableview. Questa è la stessa idea per qualsiasi controllo come già risposto in questo post: Detecting which UIButton was pressed in a UITableView

- (void) switchChanged:(id)sender 
{ 
    CGPoint switchPositionPoint = [sender convertPoint:CGPointZero toView:[self tableView]]; 
    NSIndexPath *indexPath = [[self tableView] indexPathForRowAtPoint:switchPositionPoint]; 
} 

Questo lavoro per iOS7, in precedenza ho usato [superview mittente], ma che ora restituisce un UITableViewCellContentView all'interno di un'UITableViewCellScrollView.

Problemi correlati