从UITableViewCell调用和使用UITableView?

4

我有一个UITableViewController,其中包含许多UITableViewCell。每个单元格都有一个UISwitch按钮。

这是我的UITableViewController类:

@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];
        }
     }
}

在方法loadData中,数据数组被加载(这里不重要所以我没有包含它)。

在UITableViewCell(类名:DichVu2TableViewCell)中,我设置Switch的事件Value Change,以便每当一个Switch改变值(例如ON),所有其他具有相同值“service”和“loai_goi”的单元格的Switch都将被设置为OFF。

DanhsachTableViewController *tableview = [[DanhsachTableViewController alloc] init];
    tableview.tableView.delegate = (DanhsachTableViewController *)self.superview.superview;
[tableview changeCellState:_service package:_package loaigoi:_loai_goi];

但是当我调用上述表格视图的数组"data"时,它没有对象,所以什么也没有发生。

有没有什么方法可以解决这个问题?

嗨,Oyeoj, 感谢您的帮助。

在按照您的指导操作时,我遇到了一些错误。在使用提取代码时,Xcode中出现了一些错误,因此我必须进行自定义。但是程序运行时仍然出现错误。请问您是否可以帮我检查一下我的代码。先行致谢。

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`
    }

}
2个回答

1

更加高效的方法是使用自定义代理。

  1. 您可以在UITableViewController类中声明协议。
  2. 在协议中声明changeCellState函数。
  3. UITableViewCell类中创建代理属性。
  4. 当开关值改变时,从UITableViewCell类调用代理方法。
  5. UITableViewController将自己接收消息,并分别调用该函数。

谢谢。我成功地使用了委托。 - Souchan Meijin

0

你尝试过记录 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]; 会分配一个新的DanhsachTableViewController类,而不是现有的类。

编辑

使用protocoldelegate

当使用代理时,您不需要self.superview.superview :)

在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

在 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`
    }

}

希望现在更有帮助了.. :) 干杯...


self.superview.superview在UITableView中。我使用了您的代码,但它不起作用。谢谢您的帮助! - Souchan Meijin
我按照你的代码操作,但是它没有起作用。我已经将所有的代码放在上面了。你能看一下,看看问题出在哪里吗?提前感谢。 - Souchan Meijin
哦,对不起,我在这一行中漏掉了()@interface DanhsachTableViewController () <DichVu2TableViewCellDelegate>。问题是代理没有实现,因此它没有被调用。cellLocal只是举例而已。抱歉让你感到困惑,我应该清理我的代码,或者至少添加注释。 - 0yeoj
@SouchanMeijin:很高兴能帮忙..不过我有点困惑你的问题的答案是哪个。无论如何,击掌庆祝!干杯! :) - 0yeoj
我在你的帮助下使用了委托(delegate)。但是我删除了“forUpdateIndexPath”的使用,因为我的changeCell业务不需要它。数组DATA拥有我所需的所有信息,所以我只需要在DATA中进行一些更改处理,然后重新加载表视图中的数据。方法cellForRowAtIndexPath会完成其余的事情。 - Souchan Meijin
啊..好的。很高兴我的努力能帮到您..感谢您的赞赏,先生.. :) - 0yeoj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接