如何加载UITableView有独立的子类委托和数据源



有一个UIViewController由一个UITextField和一个UITableView组成。我有一个单独的UIViewTableViewController子类,用于支持UIViewController中的UITableView的委托和数据源(默认)。我可以从UITexField到SecondViewController的文本,并将其保存到NSMutableArray,但这不是传递到UITableView。如果我只是传递一个字符串到*单元格,它显示在UITableView。下面是代码:

ViewController.h

    #import <UIKit/UIKit.h>
    #import "SecondTableViewController.h"
    @interface ViewController : UIViewController{
        SecondTableViewController *tableController;
    }
    @end
**ViewController.m**
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITableView *table;
@property (weak, nonatomic) IBOutlet UITextField *textField;
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    tableController = [[SecondTableViewController alloc] init];
    tableController.taskArray = [[NSMutableArray alloc]init];
    self.table.dataSource = tableController;
    self.table.delegate = tableController;
    self.textField.delegate = tableController;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

SecondTableViewController.h

#import <UIKit/UIKit.h>

@interface SecondTableViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>
@property NSMutableArray *taskArray;
@property NSString *taskString;

@end

SecondViewController.m

#import "SecondTableViewController.h"
#import "ViewController.h"
@implementation SecondTableViewController

-(BOOL)textFieldShouldReturn:(UITextField *)textField {
    self.taskString = [textField text];
    [textField resignFirstResponder];
    return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
    [self.taskArray addObject:self.taskString];
    [textField setText:@""];
    NSLog(@"array is %@", self.taskArray);
    [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self
                                             .self.taskArray.count-1 inSection:0]] withRowAnimation:
    UITableViewRowAnimationLeft];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.taskArray.count;
    }
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
            if (cell == nil) {
                cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
                }
        cell.textLabel.text = self.taskArray[indexPath.row];
    NSLog(@"cell ident %@", self.taskArray[indexPath.row]);
    return cell;
}


@end

你在SecondTableViewController中对tableView的引用并没有指向你在原始UIViewController中所做的tableView var,所以cellForRowAtIndexPath不会对tableView var做任何事情。

TableViewController类有一个名为tableView的属性,它已经绑定到类上,带有对其父类的引用,然后那个类成为委托和数据源。你已经破坏了与委托和数据源的链接,但没有破坏与tableView属性本身的链接。

如果你想从tableview所在的类中分离委托和数据源,那么你可以这样做,但你不需要使用UITableViewController类。你可以做一个自定义类子类化NSObject并包括所有那些委托和数据源调用。如果你这样做了那么你设置tableView的委托和数据源的代码就会像这样

 SeparateDataSourceClass *separateClass = [SeparateDataSourceClass new];
 self.table.dataSource = separateClass;
 self.table.delegate = separateClass;
 self.textField.delegate = separateClass;

差不多,但你可能明白了。

我不知道你为什么这样做。我的意思是视图控制器2控制着视图控制器1的外观和感觉!!你不能这样做!

然而,你的问题是SecondTableViewController中的self.tableView不是你设置委托的表视图。SecondTableViewController中的self.tableView是默认的表视图,它是UITableViewController的子类。

要解决这个问题有两个解决方案:

解决方案1:摆脱这种混乱的视图层次结构,并具有相同的视图控制器管理好这些东西

方案二:在右表视图对象上调用insertRowsAtIndexPaths。要做到这一点,您可以将tableView引用从ViewController传递到SecondTableViewController

最新更新