2016-04-25 4 views
1

Ich habe ein UISegmentedControl in einer UITableViewCell, die ich auf Wertänderungen im TableViewController warten muss.Verwenden von Protokollen zum Erkennen von Wertänderungen in UISegmentedControl

Bisher weiß ich, dass ich Protokolle verwenden muss, um dies zu tun, aber ich bin mir nicht sicher, wo ich den Code einfügen soll. Sollte es in der UITableViewCell sein? Im ViewController? Das ist alles ein bisschen verwirrend für mich.

Ich brauche etwas genauer zu wissen, wo ich anfangen soll, oder besser, ein Codebeispiel?

+0

Bitte definieren Wertänderungen in UITableViewController. Anzahl der Zeilen wird sich ändern? – KlimczakM

+0

Meinst du Änderungen in irgendeiner Zelle? – KlimczakM

Antwort

0

Hier wird Der Code, der das Protokoll verwendet. In diesem Beispiel können Sie die Wertänderung des Segments Control beobachten. Sie können wissen, welches Segment der Zelle angezapft wird und wissen, dass sich die Segmentdaten ändern.

// ViewController.m

#import "ViewController.h" 
#import "segmentTestCell.h" 

@interface ViewController()<UITableViewDataSource, UITableViewDelegate, segmentTestCellDelegate> 

@property (nonatomic, strong) UITableView *table; 

@end 

@implementation ViewController 
#pragma mark - LifeCycle 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    [self.table registerClass:[segmentTestCell class] forCellReuseIdentifier:@"cellId"]; 
    [self.view addSubview:self.table]; 
} 

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

#pragma mark - UITableViewDataSource, UITabBarDelegate 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return 100; 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    return 50; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    segmentTestCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellId"]; 
    cell.indexPath = indexPath; 
    if (!cell.delegate) { 
     cell.delegate = self; 
    } 
    return cell; 
} 

#pragma mark - segmentTestCellDelegate 
- (void)segmentChangeAtIndexPath:(NSIndexPath *)indexPath SelectIndex:(NSInteger)selectedIndex SelectTitle:(NSString *)selectedTitle { 
    NSLog(@"%lu - %lu - %@",indexPath.section,indexPath.row,selectedTitle); 

    // do something by yourself 
} 

#pragma mark - Getter 
- (UITableView *)table { 
    if (!_table) { 
     _table = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain]; 
     _table.allowsSelection = NO; 
     _table.dataSource = self; 
     _table.delegate = self; 
    } 
    return _table; 
} 

@end 

// segmentTestCell.h

#import <UIKit/UIKit.h> 

@protocol segmentTestCellDelegate <NSObject> 
@optional 
- (void)segmentChangeAtIndexPath: (NSIndexPath *)indexPath SelectIndex: (NSInteger)selectedIndex SelectTitle: (NSString *)selectedTitle; 
@end 

@interface segmentTestCell : UITableViewCell 

@property (nonatomic, strong) UISegmentedControl *segmentControl; 

@property (nonatomic, strong) NSIndexPath *indexPath; 
@property (nonatomic, weak) id<segmentTestCellDelegate> delegate; 

@end 

// segmentTestCell.m

#import "segmentTestCell.h" 

#define titles @[@"A",@"B",@"C"] 

@interface segmentTestCell() 

@end 

@implementation segmentTestCell 

- (void)awakeFromNib { 
    [super awakeFromNib]; 
    // Initialization code 
} 

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

    // Configure the view for the selected state 
} 

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     self.segmentControl.frame = CGRectMake(20, 10, 100, 30); 
     [self.contentView addSubview:self.segmentControl]; 
    } 
    return self; 
} 

- (void)segmentValueChange: (id)sender { 
    // do something 
    UISegmentedControl *control = (UISegmentedControl *)sender; 
    if ([self.delegate respondsToSelector:@selector(segmentChangeAtIndexPath:SelectIndex:SelectTitle:)]) { 
     [self.delegate segmentChangeAtIndexPath:_indexPath SelectIndex:control.selectedSegmentIndex SelectTitle:titles[control.selectedSegmentIndex]]; 
    } 
} 

- (UISegmentedControl *)segmentControl { 
    if (!_segmentControl) { 
     _segmentControl = [[UISegmentedControl alloc]initWithItems:titles]; 
     [_segmentControl addTarget:self action:@selector(segmentValueChange:) forControlEvents:UIControlEventValueChanged]; 
    } 
    return _segmentControl; 
} 

@end 
0

Sie können Methode in Ihrem TableViewController hinzufügen.

Fügen Sie in der cellForRow-Methode von UITableViewController den folgenden Code hinzu.

[cell.yourSegmentControl addTarget:self action:@selector(handleSegmentControlEvent:) forControlEvents: UIControlEventValueChanged]; 

Dann Verfahren in demselben Controller implementieren,

- (void)handleSegmentControlEvent:(id)sender{ 
} 

Hoffe, es hilft.

+0

Das von 'cellForRow' aufzurufen, ist eine sehr schlechte Idee, besonders wenn er' dequeueReusableCellWithIdentifier' benutzt ... es wird zu oft aufgerufen. – KlimczakM

+0

@KlimczakM Ich benutze Zellen wieder. Was wäre die beste Praxis? –

+0

@ Ronny-André Bendiksen Es kommt darauf an, was genau Sie unter "Wertänderungen im TableViewController" verstehen. Bitte beschreiben Sie, was geschehen soll, um 'UISegmentedControl'-Änderungen auszulösen. – KlimczakM

3

Von dem, was wir in Kommentaren gesprochen haben, möchten Sie UITableView jedes Mal neu laden, wenn der Benutzer UISegmentedControl Auswahl ändert.

Zuerst müssen Sie diese zu Ihrem UISegmentedControl hinzuzufügen:

self.segmentedControl.addTarget(self, action: "segmentedControlIndexChanged", forControlEvents: .ValueChanged) 

Aber tun dies nur nach UISegmentedControl Initiation, und nicht in cellForRow wie in der zweiten Antwort, weil es auf jeder Zelle Wiederverwendung aufgerufen werden würde (was wird viel, wenn Sie mehr Zellen haben, als auf dem Bildschirm erscheinen können).

Dann tun Sie Sie Logik in dieser Methode:

func segmentedControlIndexChanged() { 
    // change your UITableView data or even swap your UITableViews (if you have 2) 
} 

Bitte denken Sie daran, dass, wenn Sie den Index manuell ändern, müssen Sie auch manuell Ereignis ändern aufzurufen:

segmentedControl.sendActionsForControlEvents(.ValueChanged) 
+1

Vielen Dank, das ist eine saubere und einfache Lösung :) –

Verwandte Themen