【问题标题】:Call and use uitableview from uitableviewcell?从 uitableviewcell 调用和使用 uitableview?
【发布时间】:2015-06-23 09:13:55
【问题描述】:

我有一个带有许多 UITableViewCell 的 UITableViewController。每个单元格都有一个 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];
        }
     }
}

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

在 UITableViewCell(类名:DichVu2TableViewCell)中,我设置了 Switch 的事件值更改,以便每次 Switch 更改值(例如 ON)时,具有相同值“服务”和“loai_goi”的所有其他单元格的开关将设置为关闭。

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

但是当我调用时,上面 tableview 的数组“数据”有 0 个对象,所以什么也没发生。

有什么办法吗?

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

}

【问题讨论】:

    标签: ios objective-c iphone xcode tableviewcell


    【解决方案1】:

    更有效的方法是使用自定义委托。

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

    【讨论】:

    • 谢谢。我成功使用了委托。
    【解决方案2】:

    您是否尝试过记录 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
    

    同时

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

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

    【讨论】:

    • selft.superview.superview 在 UITableView 中。我使用你的代码,但它不起作用。感谢您的帮助!
    • 我遵循了您的代码,但它不起作用。我上面有我的所有代码。你能看看有什么问题吗?提前致谢。
    • 哦,是的.. 对不起,我会错过@interface DanhsachTableViewController () &lt;DichVu2TableViewCellDelegate&gt; 行中的(),问题是委托没有实现,因此它没有被调用。 cellLocal 只是举例......抱歉让你感到困惑,我应该清理我的代码,或者至少添加 cmets..
    • @SouchanMeijin:很高兴为您提供帮助.. 我很困惑这是您问题的答案。无论如何.. 嗨!干杯! :)
    • 我在您的帮助下使用了委托。但我删除了“forUpdateIndexPath”的使用,因为我在 changeCell 中的业务不需要它。数组 DATA 有我需要的所有信息,所以我只需要在 DATA 中处理这个数组中的一些变化,然后我在表视图中重新加载数据。方法 cellForRowAtIndexPath 做剩下的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多