Objective-c UITableView separate class cellForRowAtIndexPath does not get called

北战南征 提交于 2020-01-24 01:22:51

问题


There are a huge number of questions relating to this topic but I have not yet come across my use case so here goes.

This is my first couple weeks in OBJ-C so I have no clue what I am doing with some of this stuff...

What I Want

I do not particularly enjoy seeing so many classes in OBJ-C that overload the view controller classes with every and any function on this earth. It looks dirty and feels gross as far as OOP goes. In my use case I don't have a full screen table just a little one to hold 10 things. Therefore it's quite inappropriate to use a full UITableViewController. Instead, I want to have all my table delegate specific methods to be in a UITableView sub-class. NOT in a UITableViewController or a ViewController with a UITableView property. This should be mega simple yet...

The Problem

No matter what I do I cannot seem to get the method cellForRowAtIndexPath to fire. I know enough to know that this stuff relies heavily on the delegate and datasource assignment... however since I have a separate UITableView class that uses the <UITableViewDelegate, UITableViewDataSource> delegations I don't think I should have to do any sort of assignment at all!

What am I gonna write?? self.delegate = self ? or worse, in the ViewController that calls this UITableView class, self.tasksTable.delgate = self.tasksTable ? Eww... gross

Here is what I am doing in code.

The Code

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

I am also having a hard time figuring out what to set as the datasource. In other languages you would typically set the DataSource object with self.DataSource = [self getAllTasks]... however all the tuturials I have done thus far all tend to use some weird ad-hoc NSArray or NSDictionary to then correlate the index of the table functions with the index of the array or dictionary keys... This confuses me greatly as to why I can't just set the DataSource object and have the table know to iterate over it's data.

My conclusion is that this isn't firing because it thinks the DataSource object is empty and there are no rows? (which it is, but like I said people seem to get Tables to work fine on YouTube doing this)

Thanks.


回答1:


TasksTableView class is derived from UITableView class & You are implementing the UITableview delegates in the same class. This will not work.

Instead of creating a UITableView subclass. Create TasksTableView class as NSObject sub class. And pass the tableview object from where you added a tableview.

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

And set that table view delegate to self(TasksTableView object) while init the 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;
}

Now your delegate methods will trigger for that specific tableview



来源:https://stackoverflow.com/questions/44655124/objective-c-uitableview-separate-class-cellforrowatindexpath-does-not-get-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!