使用协议检测 UISegmentedControl 中的值变化
Using protocols for detecting value changes in UISegmentedControl
我在 UITableViewCell 中有一个 UISegmentedControl,我需要监听表中的值变化ViewController。
到目前为止,我知道我必须使用协议才能执行此操作,但我不确定将代码放在哪里。它应该在 UITableViewCell 中吗?在 ViewController?这让我有点困惑。
我需要一些关于从哪里开始的精确定位,或者更好的是一些代码示例?
您可以在 tableViewController 中添加方法。
在 UITableViewController 的 cellForRow 方法中添加以下代码。
[cell.yourSegmentControl addTarget:self action:@selector(handleSegmentControlEvent:) forControlEvents: UIControlEventValueChanged];
然后在同一个控制器中实现方法,
- (void)handleSegmentControlEvent:(id)sender{
}
希望对您有所帮助。
根据我们在评论中的讨论,您希望每次用户更改 UISegmentedControl
选择时重新加载 UITableView
。
首先您需要将此添加到您的 UISegmentedControl
:
self.segmentedControl.addTarget(self, action: "segmentedControlIndexChanged", forControlEvents: .ValueChanged)
但是在 UISegmentedControl
启动后才执行此操作,而不是像第二个答案那样在 cellForRow
中执行此操作,因为它会在每次单元格重用时调用(如果您有更多单元格,将会调用很多细胞比可以出现在屏幕上)。
然后你在这个方法中做你的逻辑:
func segmentedControlIndexChanged() {
// change your UITableView data or even swap your UITableViews (if you have 2)
}
请记住,当您手动更改索引时,您也需要手动调用事件更改:
segmentedControl.sendActionsForControlEvents(.ValueChanged)
这里是使用protocol.In这个示例的代码,你可以观察segmentControl的值变化。可以知道哪个cell的segment被点击了,segment数据变化了。
// 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
我在 UITableViewCell 中有一个 UISegmentedControl,我需要监听表中的值变化ViewController。
到目前为止,我知道我必须使用协议才能执行此操作,但我不确定将代码放在哪里。它应该在 UITableViewCell 中吗?在 ViewController?这让我有点困惑。
我需要一些关于从哪里开始的精确定位,或者更好的是一些代码示例?
您可以在 tableViewController 中添加方法。
在 UITableViewController 的 cellForRow 方法中添加以下代码。
[cell.yourSegmentControl addTarget:self action:@selector(handleSegmentControlEvent:) forControlEvents: UIControlEventValueChanged];
然后在同一个控制器中实现方法,
- (void)handleSegmentControlEvent:(id)sender{
}
希望对您有所帮助。
根据我们在评论中的讨论,您希望每次用户更改 UISegmentedControl
选择时重新加载 UITableView
。
首先您需要将此添加到您的 UISegmentedControl
:
self.segmentedControl.addTarget(self, action: "segmentedControlIndexChanged", forControlEvents: .ValueChanged)
但是在 UISegmentedControl
启动后才执行此操作,而不是像第二个答案那样在 cellForRow
中执行此操作,因为它会在每次单元格重用时调用(如果您有更多单元格,将会调用很多细胞比可以出现在屏幕上)。
然后你在这个方法中做你的逻辑:
func segmentedControlIndexChanged() {
// change your UITableView data or even swap your UITableViews (if you have 2)
}
请记住,当您手动更改索引时,您也需要手动调用事件更改:
segmentedControl.sendActionsForControlEvents(.ValueChanged)
这里是使用protocol.In这个示例的代码,你可以观察segmentControl的值变化。可以知道哪个cell的segment被点击了,segment数据变化了。
// 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