问题
I've been going at this for about 3 hours now, and I'm finally throwing in the towel to y'all. I have 2 UITableView
in my view, one of which is a forum board to leave comments and what not, and the second UITableView
is used to mention people. the issue I am having is that both tableview counts
are being affected even if i only want to update just 1 of the tableviews.
I set the delegate/datasource in the viewdidload
self.mentionTableView.delegate = self;
self.mentionTableView.dataSource = self;
self.mentionTableView.tag = 1;
self.forumTable.delegate = self;
self.forumTable.dataSource = self;
self.forumTable.tag = 2;
and if i actually do not load feedArray
which is where forumTable
gets its data from, the mention portion works perfectly. I've figured out that if matchedNames.count
<feedArray.count
everything works fine, but if matchedNames.count
>feedArray.count
it crashes and this is the error i get
-[__NSCFArray objectAtIndex:]: index (1) beyond bounds (1)
which means that i only have 1 item in feedArray
and matchedNames
has more than one.
inside of
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
i have used these codes to try to make it work and still nothing, ive even done combinations of them.
1)
if ([tableView isEqual: mentionTableView]){
NSLog(@"%@",matchedNames);
NSLog(@"%i",matchedNames.count);
return [matchedNames count];
} else if([tableView isEqual:forumTable]){
return [feedArray count];
}
2)
if (tableView == mentionTableView){
NSLog(@"%@",matchedNames);
NSLog(@"%i",matchedNames.count);
return [matchedNames count];
} else if(tableView == commentTable){
return [feedArray count];
}
3)
if (tableView.tag == 1){
NSLog(@"%@",matchedNames);
NSLog(@"%i",matchedNames.count);
return [matchedNames count];
} else if(tableView.tag == 2){
return [feedArray count];
}
and I know I didnt have to do the else if
but I was just trying to be specific to maybe avoid this issue.
this is my cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.tag == 1){
CGAffineTransform transform = CGAffineTransformMakeRotation(3.14);
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.transform = transform;
cell.textLabel.text = [self.matchedNames objectAtIndex:indexPath.row];
return cell;
} else {
static NSString *CellIdentifier = @"commentCell";
commentsCustomCell *cell =(commentsCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[commentsCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSDictionary *feedPost = [feedArray objectAtIndex:indexPath.row];
NSString *checkIFempty = [feedPost objectForKey:@"isForum_empty"];
if (![checkIFempty isEqualToString:@"1"]) {
cell.noCommentsLabel.text = nil;
} else {
cell.noCommentsLabel.text = @"No Comments";
cell.forumComment = nil;
}
NSString *username =[feedPost objectForKey:@"Username"];
NSString *final_time =[feedPost objectForKey:@"final_time"];
NSString *userIDforPic =[feedPost objectForKey:@"UserID"];
finalComment = [feedPost objectForKey:@"comment"];
cell.forumComment.text = finalComment;
return cell;
}
}
if my question is confusing i do apologize, I haven't slept 36 hours. thanks for looking at my question!
回答1:
You really really really should consider to refactor your code and separate this two tableViews in different viewControllers.
You can, for example, use containerViews inside your main viewController and put the tableview in the container view controllers.
TableView delegates use a lot of code, and set different tableViews to the same controller will always end up like this, messing the code and giving more trouble than it should be.
回答2:
There are a few techniques you can use that will help clean up your code and allow for a less messy solution. I will take a wack at explaining this.
One first easy step is to create a property or method that gives you the array of data based on the tableView or tag:
- (NSArray *)dataForInteger:(NSUInteger)value {
return @[self.matchedNames, self.feedArray][value];
}
// you can also make this a readonly property for easier access
In order to use the above method you need to make sure the tag for the table that needs matchedNames
is 0
and feedArray
is 1
(or you could use a simple if/else
statement and make the tags whatever you want.
Now look how easy this makes your future logic!
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
[[self dataForInteger:tableView.tag] count];
}
That's it!
Next, you could potentially create a method like:
- (UITableViewCell *)emptyCellForTableView:(UITableView *)tableView {
NSString *cellIdentifier = @[@"CellIdentifierONe", @"CellIdentifierTWO"][tableView.tag];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
// the only messy looking logic
if (!tableView.tag) { // tableView.tag == 0
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
CGAffineTransform transform = CGAffineTransformMakeRotation(3.14);
cell.transform = transform;
} else {
// make sure "CommentsCustomCell" is a class and not an instance (like your example)
cell = [[CommentsCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
}
return cell;
}
Then in your tableView:cellForRowAtIndexPath:
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self emptyCellForTableView:tableView];
NSArray *dataArray = [self dataForInteger:tableView.tag];
// setup all custom UITableViewCell's to have a property or setter "data"
if ([cell respondsToSelector:@selector(setData:)]) {
// I will explain this a bit later
cell.data = dataArray[indexPath.row];
} else {
// based on your example this was an NSString array
self.textLabel.text = dataArray[indexPath.row];
}
}
Now the cell.data = dataArray[indexPath.row];
is per Apple's example how setup data for custom UITableViewCells
. Just create a property called data, that takes in it's setter looks something like this (for your example):
// CommentsCustomCell.m
- (void)setData:(id /*or custom class, in this case you use NSDictionary*/)data {
_data = data;
// NTOE: I just copied your example above, I am sure there is a nicer way to do this but you get the idea.
NSDictionary *feedPost = (NSDictionary *)data;
NSString *checkIFempty = [feedPost objectForKey:@"isForum_empty"];
if (![checkIFempty isEqualToString:@"1"]) {
cell.noCommentsLabel.text = nil;
} else {
cell.noCommentsLabel.text = @"No Comments";
cell.forumComment = nil;
}
NSString *username =[feedPost objectForKey:@"Username"];
NSString *final_time =[feedPost objectForKey:@"final_time"];
NSString *userIDforPic =[feedPost objectForKey:@"UserID"];
finalComment = [feedPost objectForKey:@"comment"];
cell.forumComment.text = finalComment;
}
The reason why a solution like this is so beautiful is if you ever wanted to use a different custom UITableViewCell
all you would need to do is change the Empty Cell Creation method to create that class, and that is basically it (This also allows you to make all of your cell's IBOutlet
s private!). As long as the new class has a data
property your main controller does not care! It just sends the data through. This also allows you to scale it appropriately. If all the tableView
's used custom cells you could easily have a dozen tableviews in the same viewController
without needing much extra logic (just add it the array, set the tag, and make sure the cell creation method creates the appropriate cell!).
I typed this up pretty quickly so there is probably some missing logic or typos. I will fix any if they are pointed out. Good luck.
来源:https://stackoverflow.com/questions/18146434/2-uitableview-in-a-uiviewcontroller-affecting-each-other