Objective-c UITableView 分开 class cellForRowAtIndexPath 没有被调用

Objective-c UITableView separate class cellForRowAtIndexPath does not get called

有大量与此主题相关的问题,但我还没有遇到我的用例,所以这里开始。

这是我在 OBJ-C 的头几周,所以我不知道我在用这些东西做什么......

我想要的

我不是特别喜欢在 OBJ-C 中看到如此多的 classes 使视图控制器 classes 超载这个世界上的每一个功能。就 OOP 而言,它看起来很脏而且感觉很恶心。在我的用例中,我没有全屏 table 只有一个小屏幕可以容纳 10 个东西。因此,使用完整的 UITableViewController 是非常不合适的。相反,我想让我所有的 table 委托特定方法都在 UITableView sub-class 中。不在 UITableViewController 或带有 UITableView 属性 的 ViewController 中。这应该非常简单......

问题

无论我做什么,我似乎都无法启动方法 cellForRowAtIndexPath。我知道这些东西在很大程度上依赖于委托和数据源分配......但是因为我有一个单独的 UITableView class 使用 <UITableViewDelegate, UITableViewDataSource> 委托我认为我不应该做任何类型的作业!

我要写什么?? self.delegate = self ?或者更糟的是,在调用此 UITableView class、self.tasksTable.delgate = self.tasksTable 的 ViewController 中? Eww...恶心

这是我在代码中所做的。

代码

TasksTableView.h

#import <UIKit/UIKit.h>

@interface TasksTableView : UITableView <UITableViewDelegate, UITableViewDataSource> {
    NSArray *tasksData;
}

- (NSMutableArray *)getAllTasks;

@end

TasksTableView.m

#import "TasksTableView.h"
#import "NSObject+RemoteFetch.h" //<--I use this to fetch, obvs

@interface TasksTableView ()
@property (nonatomic, strong) NSString *cellId;
@end


@implementation TasksTableView

- (instancetype)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];

    if(self) {
        _cellId = @"AllTasksTableCell";
        tasksData = [self getAllTasks];
    }

    return self;
}


#pragma mark - Custom Table Functionality

- (NSMutableArray *)getAllTasks {
    @try {
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        NSString *TASKS_URL = [userDefaults objectForKey:@"tasksUrl"];

        NSObject *fetcher = [[NSObject alloc] init];
        NSDictionary *response = [fetcher fetchAPICall:TASKS_URL httpRequestType:@"GET" requestBodyData:nil];

        return [response objectForKey:@"data"];

    } @catch (NSException *exception) {
        NSLog(@"could not get tasks, error: %@", exception);

        return nil;
    }
}


#pragma mark - UITableView DataSource Methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [tasksData count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    //<--  NEVER GETS HERE

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:_cellId];

    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:_cellId];
    }

    cell.textLabel.text = [tasksData objectAtIndex:indexPath.row];

    return cell;
}

@end

我也很难确定将什么设置为数据源。在其他语言中,您通常会使用 self.DataSource = [self getAllTasks]... =] 函数与数组或字典键的索引......这让我很困惑,为什么我不能只设置 DataSource 对象并让 table 知道迭代它的数据。

我的结论是,这不是触发,因为它认为 DataSource 对象是空的并且没有行? (确实如此,但就像我说的那样,人们似乎可以让 Tables 在 YouTube 上正常工作)

谢谢。

TasksTableView class 派生自 UITableView class 并且您正在同一个 class 中实现 UITableview 代表。这行不通。

而不是创建 UITableView subclass。创建 TasksTableView class 作为 NSObject 子 class。并从添加 tableview 的位置传递 tableview 对象。

@interface TasksTableView : NSObject <UITableViewDelegate, UITableViewDataSource> {
    NSArray *tasksData;
   __weak UITableView *tableView;
}

并将 table 视图委托设置为 self(TasksTableView 对象),而 init TasksTableView Class

- (instancetype)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];

    if(self) {
       _cellId = @"AllTasksTableCell";
       tasksData = [self getAllTasks];
       self.tableView.delgate = self;
       self.tableView.datasource = self;
    }

    return self;
}

现在您的 delegate 方法将针对特定 tableview

触发