从uitableviewcell调用并使用uitableview?
Call and use uitableview from uitableviewcell?
我有一个带有许多 UITableViewCell 的 UITableViewController。每个 Cell 都有一个 UISwitch Button。
这是我的 UITableViewController Class:
@implementation DanhsachTableViewController{
NSMutableArray *data;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self loadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DichVu2TableViewCell *cell = (DichVu2TableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"dscell"];
NSDictionary *dataCell = data[indexPath.row];
cell.service = dataCell[@"service"];
cell.package = dataCell[@"package"];
cell.loai_goi = dataCell[@"loai_goi"];
return cell;
}
-(void) changeCellState:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi{
for (int i =0;i<data.count;i++){
DichVu2TableViewCell *cellLocal = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
if ([service isEqualToString:cellLocal.service] && ![package isEqualToString:cellLocal.package] && [loai_goi isEqualToString:cellLocal.loai_goi]){
[cellLocal.sudung setOn:NO animated:YES];
}
}
}
"Data" 数组是在方法 loadData 中加载的(这里不重要,所以我不包括它)。
在 UITableViewCell(class 名称:DichVu2TableViewCell)中,我设置了 Switch 的事件值更改,以便每次 Switch 更改值(例如 ON)时,所有其他具有相同值的单元格的开关 "service" 和 "loai_goi" 将被设置为关闭。
DanhsachTableViewController *tableview = [[DanhsachTableViewController alloc] init];
tableview.tableView.delegate = (DanhsachTableViewController *)self.superview.superview;
[tableview changeCellState:_service package:_package loaigoi:_loai_goi];
但是当我调用时,上面tableview 的数组"data" 有0 个对象,所以什么也没有发生。
有什么办法吗?
嗨,Oyeoj,
感谢您的帮助。
按照您的指导,我遇到了一点问题。 xcode 当我使用 extract your code 时有一些错误所以我必须自定义。但是当运行时程序还是有错误。你能帮我检查一下我的代码吗?提前致谢。
DichVu2TableViewCell.h
@class DichVu2TableViewCell;
//Change : NSObject to <NSObject> because XCode 6.3 has error.
@protocol DichVu2TableViewCellDelegate <NSObject>
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi;
@end
@interface DichVu2TableViewCell : UITableViewCell
@property (weak) id <DichVu2TableViewCellDelegate> delegate;
@end
DichVu2TableViewCell.m
@implementation DichVu2TableViewCell
….
- (void)someSwitchingEvent
{
[self.delegate changeCell:self state:_service package:_package loaigoi:_loai_goi];
}
@end
DanhsachTableViewController.h
@interface DanhsachTableViewController : UITableViewController
@property (strong,nonatomic) NSString *loaitb;
@property (strong,nonatomic) NSString *type;
@property (strong,nonatomic) NSString *name;
@property NSMutableArray *pre_inuse_;
@property NSMutableArray *data_inuse_;
@property NSMutableArray *vas_inuse_;
@end
DanhsachTableViewController.m
#import "DichVu2TableViewCell.h"
//Change <DichVu2TableViewCellDelegate> to (DichVu2TableViewCellDelegate) because XCode 6.3 has error.
@interface DanhsachTableViewController (DichVu2TableViewCellDelegate)
@property (nonatomic) NSIndexPath *forUpdateIndexPath;
@end
@implementation DanhsachTableViewController{
NSMutableArray *data;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DichVu2TableViewCell *cell = (DichVu2TableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"dscell"];
NSDictionary *dataCell = data[indexPath.row];
cell.service = dataCell[@"service"];
cell.package = dataCell[@"package"];
cell.loai_goi = dataCell[@"loai_goi"];
cell.kieu_goi = dataCell[@"kieu_goi"];
[cell.sudung setOn:NO animated:YES];
cell.delegate = self;
//Change cellLocal —> cell because there are no cellLocal avaiable. And Program error when run to this row.
[cell.sudung setOn:(self.forUpdateIndexPath == indexPath) animated:YES];
return cell;
}
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi
{
//Add cellLocal —> cell because there are no cellLocal avaiable
DichVu2TableViewCell *cellLocal = (DichVu2TableViewCell *)[self.tableView cellForRowAtIndexPath:self.forUpdateIndexPath];
if ([service isEqualToString:cellLocal.service] && ![package isEqualToString:cellLocal.package] && [loai_goi isEqualToString:cellLocal.loai_goi]){
// get the indexPath of the cell
self.forUpdateIndexPath = [self.tableView indexPathForCell:sender];
// update the date source
NSMutableDictionary *dataCell = [data[self.forUpdateIndexPath.row] mutableCopy];
[dataCell setObject:service forKey:@"service"];
[dataCell setObject:package forKey:@"package"];
[dataCell setObject:loai_goi forKey:@"loai_goi"];
// you dont need the for-statement just reload the table
[self.tableView reloadData];
// then update the switch inside `- cellForRowAtIndexPath`
}
}
您尝试过记录 self.superview.superview;
吗?你确定是 UIViewController
类型吗?
如果是:
不打电话[[DanhsachTableViewController alloc]
改为使用父视图中的 DanhsachTableViewController
DanhsachTableViewController *tableview = (DanhsachTableViewController *)self.superview.superview;
[tableview changeCellState:_service package:_package loaigoi:_loai_goi];
这个
DanhsachTableViewController *tableview = [[DanhsachTableViewController alloc] init];
分配 new DanhsachTableViewController
class 而不是现有的
编辑
使用 protocol
和 delegate
使用委托时,您不需要 self.superview.superview
:)
UNDER DichVu2TableViewCell
@class DichVu2TableViewCell;
@protocol DichVu2TableViewCellDelegate <NSObject>
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi;
@end
@interface DichVu2TableViewCell : UIViewController
@property (weak) id <DichVu2TableViewCellDelegate> delegate;
@end
@implementaion DichVu2TableViewCell
..
- (void)someSwitchingEvent
{
[self.delegate changeCell:self state:_service package:_package loaigoi:_loai_goi];
}
@end
而
UNDER DanhsachTableViewController
// assuming you alreading imported the `DichVu2TableViewCell` like
//
// #import "DichVu2TableViewCell.h"
//
// set the delegate
@interface DanhsachTableViewController () <DichVu2TableViewCellDelegate>
@property (nonatomic) NSIndexPath *forUpdateIndexPath;
@end
// then implement the method from the delegate under implementation file
@implementation DanhsachTableViewController
{
NSMutableArray *data;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DichVu2TableViewCell *cell = (DichVu2TableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"dscell"];
NSDictionary *dataCell = data[indexPath.row];
cell.service = dataCell[@"service"];
cell.package = dataCell[@"package"];
cell.loai_goi = dataCell[@"loai_goi"];
// this is the magic .. :)
//--
cell.delegate = self;
[cell.sudung setOn:(self.forUpdateIndexPath == indexPath) animated:YES];
//--
return cell;
}
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi
{
// `self.forUpdateIndexPath` is declared as property
if ([service isEqualToString:service] && ![package isEqualToString:package] && [loai_goi isEqualToString:loai_goi]){
// get the indexPath of the cell
self.forUpdateIndexPath = [self.tableView indexPathForCell:sender];
// update the date source
NSMutableDictionary *dataCell = [data[self.forUpdateIndexPath.row] mutableCopy];
[dataCell setObject:service forKey:@"service"];
[dataCell setObject:package forKey:@"package"];
[dataCell setObject:loai_goi forKey:@"loai_goi"];
// you dont need the for-statement just reload the table
[self.tableView reloadData];
// then the switch will be updated inside `- cellForRowAtIndexPath`
}
}
希望这现在更有帮助..:)干杯...
一种更有效的方法是使用自定义委托。
- 您可以在
UITableViewController
class 中声明一个协议。
- 在协议中声明
changeCellState
函数。
- 在
UITableViewCell
class 中创建委托 属性。
- 当 switch 值改变时,从
UITableViewCell
class 调用委托方法。
UITableViewController
会自己接收消息,并分别调用函数
我有一个带有许多 UITableViewCell 的 UITableViewController。每个 Cell 都有一个 UISwitch Button。
这是我的 UITableViewController Class:
@implementation DanhsachTableViewController{
NSMutableArray *data;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self loadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DichVu2TableViewCell *cell = (DichVu2TableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"dscell"];
NSDictionary *dataCell = data[indexPath.row];
cell.service = dataCell[@"service"];
cell.package = dataCell[@"package"];
cell.loai_goi = dataCell[@"loai_goi"];
return cell;
}
-(void) changeCellState:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi{
for (int i =0;i<data.count;i++){
DichVu2TableViewCell *cellLocal = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
if ([service isEqualToString:cellLocal.service] && ![package isEqualToString:cellLocal.package] && [loai_goi isEqualToString:cellLocal.loai_goi]){
[cellLocal.sudung setOn:NO animated:YES];
}
}
}
"Data" 数组是在方法 loadData 中加载的(这里不重要,所以我不包括它)。
在 UITableViewCell(class 名称:DichVu2TableViewCell)中,我设置了 Switch 的事件值更改,以便每次 Switch 更改值(例如 ON)时,所有其他具有相同值的单元格的开关 "service" 和 "loai_goi" 将被设置为关闭。
DanhsachTableViewController *tableview = [[DanhsachTableViewController alloc] init];
tableview.tableView.delegate = (DanhsachTableViewController *)self.superview.superview;
[tableview changeCellState:_service package:_package loaigoi:_loai_goi];
但是当我调用时,上面tableview 的数组"data" 有0 个对象,所以什么也没有发生。
有什么办法吗?
嗨,Oyeoj, 感谢您的帮助。
按照您的指导,我遇到了一点问题。 xcode 当我使用 extract your code 时有一些错误所以我必须自定义。但是当运行时程序还是有错误。你能帮我检查一下我的代码吗?提前致谢。
DichVu2TableViewCell.h
@class DichVu2TableViewCell;
//Change : NSObject to <NSObject> because XCode 6.3 has error.
@protocol DichVu2TableViewCellDelegate <NSObject>
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi;
@end
@interface DichVu2TableViewCell : UITableViewCell
@property (weak) id <DichVu2TableViewCellDelegate> delegate;
@end
DichVu2TableViewCell.m
@implementation DichVu2TableViewCell
….
- (void)someSwitchingEvent
{
[self.delegate changeCell:self state:_service package:_package loaigoi:_loai_goi];
}
@end
DanhsachTableViewController.h
@interface DanhsachTableViewController : UITableViewController
@property (strong,nonatomic) NSString *loaitb;
@property (strong,nonatomic) NSString *type;
@property (strong,nonatomic) NSString *name;
@property NSMutableArray *pre_inuse_;
@property NSMutableArray *data_inuse_;
@property NSMutableArray *vas_inuse_;
@end
DanhsachTableViewController.m
#import "DichVu2TableViewCell.h"
//Change <DichVu2TableViewCellDelegate> to (DichVu2TableViewCellDelegate) because XCode 6.3 has error.
@interface DanhsachTableViewController (DichVu2TableViewCellDelegate)
@property (nonatomic) NSIndexPath *forUpdateIndexPath;
@end
@implementation DanhsachTableViewController{
NSMutableArray *data;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DichVu2TableViewCell *cell = (DichVu2TableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"dscell"];
NSDictionary *dataCell = data[indexPath.row];
cell.service = dataCell[@"service"];
cell.package = dataCell[@"package"];
cell.loai_goi = dataCell[@"loai_goi"];
cell.kieu_goi = dataCell[@"kieu_goi"];
[cell.sudung setOn:NO animated:YES];
cell.delegate = self;
//Change cellLocal —> cell because there are no cellLocal avaiable. And Program error when run to this row.
[cell.sudung setOn:(self.forUpdateIndexPath == indexPath) animated:YES];
return cell;
}
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi
{
//Add cellLocal —> cell because there are no cellLocal avaiable
DichVu2TableViewCell *cellLocal = (DichVu2TableViewCell *)[self.tableView cellForRowAtIndexPath:self.forUpdateIndexPath];
if ([service isEqualToString:cellLocal.service] && ![package isEqualToString:cellLocal.package] && [loai_goi isEqualToString:cellLocal.loai_goi]){
// get the indexPath of the cell
self.forUpdateIndexPath = [self.tableView indexPathForCell:sender];
// update the date source
NSMutableDictionary *dataCell = [data[self.forUpdateIndexPath.row] mutableCopy];
[dataCell setObject:service forKey:@"service"];
[dataCell setObject:package forKey:@"package"];
[dataCell setObject:loai_goi forKey:@"loai_goi"];
// you dont need the for-statement just reload the table
[self.tableView reloadData];
// then update the switch inside `- cellForRowAtIndexPath`
}
}
您尝试过记录 self.superview.superview;
吗?你确定是 UIViewController
类型吗?
如果是:
不打电话[[DanhsachTableViewController alloc]
改为使用父视图中的 DanhsachTableViewController
DanhsachTableViewController *tableview = (DanhsachTableViewController *)self.superview.superview;
[tableview changeCellState:_service package:_package loaigoi:_loai_goi];
这个
DanhsachTableViewController *tableview = [[DanhsachTableViewController alloc] init];
分配 new DanhsachTableViewController
class 而不是现有的
编辑
使用 protocol
和 delegate
使用委托时,您不需要 self.superview.superview
:)
UNDER DichVu2TableViewCell
@class DichVu2TableViewCell;
@protocol DichVu2TableViewCellDelegate <NSObject>
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi;
@end
@interface DichVu2TableViewCell : UIViewController
@property (weak) id <DichVu2TableViewCellDelegate> delegate;
@end
@implementaion DichVu2TableViewCell
..
- (void)someSwitchingEvent
{
[self.delegate changeCell:self state:_service package:_package loaigoi:_loai_goi];
}
@end
而
UNDER DanhsachTableViewController
// assuming you alreading imported the `DichVu2TableViewCell` like
//
// #import "DichVu2TableViewCell.h"
//
// set the delegate
@interface DanhsachTableViewController () <DichVu2TableViewCellDelegate>
@property (nonatomic) NSIndexPath *forUpdateIndexPath;
@end
// then implement the method from the delegate under implementation file
@implementation DanhsachTableViewController
{
NSMutableArray *data;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DichVu2TableViewCell *cell = (DichVu2TableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"dscell"];
NSDictionary *dataCell = data[indexPath.row];
cell.service = dataCell[@"service"];
cell.package = dataCell[@"package"];
cell.loai_goi = dataCell[@"loai_goi"];
// this is the magic .. :)
//--
cell.delegate = self;
[cell.sudung setOn:(self.forUpdateIndexPath == indexPath) animated:YES];
//--
return cell;
}
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi
{
// `self.forUpdateIndexPath` is declared as property
if ([service isEqualToString:service] && ![package isEqualToString:package] && [loai_goi isEqualToString:loai_goi]){
// get the indexPath of the cell
self.forUpdateIndexPath = [self.tableView indexPathForCell:sender];
// update the date source
NSMutableDictionary *dataCell = [data[self.forUpdateIndexPath.row] mutableCopy];
[dataCell setObject:service forKey:@"service"];
[dataCell setObject:package forKey:@"package"];
[dataCell setObject:loai_goi forKey:@"loai_goi"];
// you dont need the for-statement just reload the table
[self.tableView reloadData];
// then the switch will be updated inside `- cellForRowAtIndexPath`
}
}
希望这现在更有帮助..:)干杯...
一种更有效的方法是使用自定义委托。
- 您可以在
UITableViewController
class 中声明一个协议。 - 在协议中声明
changeCellState
函数。 - 在
UITableViewCell
class 中创建委托 属性。 - 当 switch 值改变时,从
UITableViewCell
class 调用委托方法。 UITableViewController
会自己接收消息,并分别调用函数