问题
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