Reputation: 43
I have a UITableViewController with many UITableViewCell. Each Cell have a UISwitch Button.
Here is my 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" array was loaded in method loadData (not important here so I don't include it).
In UITableViewCell (class name: DichVu2TableViewCell), I set event Value Change of Switch so that each time a Switch change value (ON for example), all other cell's switch which have the same value "service" and "loai_goi" will be set OFF.
DanhsachTableViewController *tableview = [[DanhsachTableViewController alloc] init];
tableview.tableView.delegate = (DanhsachTableViewController *)self.superview.superview;
[tableview changeCellState:_service package:_package loaigoi:_loai_goi];
But when I call, the array "data" of above tableview have 0 object so nothing happened.
Is there any way to do that?
Hi Oyeoj, Thanks for your help.
I have a little problem when followed your guide. There are some error in xcode when I use extract your code so I have to customize. But the program still has error when running. Would you please help me review my code. Thanks in advance.
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`
}
}
Upvotes: 4
Views: 886
Reputation: 4550
Have you tried logging self.superview.superview;
? are your sure is in type UIViewController
?
if so:
Do not call [[DanhsachTableViewController alloc]
instead use the DanhsachTableViewController
from your parentview
DanhsachTableViewController *tableview = (DanhsachTableViewController *)self.superview.superview;
[tableview changeCellState:_service package:_package loaigoi:_loai_goi];
This
DanhsachTableViewController *tableview = [[DanhsachTableViewController alloc] init];
assigns a new DanhsachTableViewController
class and not the existing one.
Edit
USING protocol
and delegate
When using delegate you dont need the 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
while
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`
}
}
Hope this is more helpful now.. :) Cheers...
Upvotes: 0
Reputation: 4203
A more efficient method would be to use custom delegates.
UITableViewController
class.changeCellState
function in the protocol.UITableViewCell
class.UITableViewCell
class when the switch value is changed.UITableViewController
will itself receive the message, and the function will be called respectively.Upvotes: 1