您的位置:首页 > 产品设计 > UI/UE

UITableView的reloadData方法,不执行cellForRow方法,

2015-11-16 12:57 555 查看
首先是只有tableview将要显示在window上的时候才会进入cellForRow方法。

像self.tableView.delegate = self;啊,dataSource数组为空啊,相信都检查过了。

也许你会说,我的tableview添加了啊,但是显示一片空白,这时候你给tableview设置个背景色看看,也许你就会发现,tableview并没有显示出来。
原因可能有多种,譬如我的原因是:

ios7以前的版本,subviews不随superview的变化而变化,也就是view的clip属性可能设置错了。

如果你设置了tableview的size为(100,100),但是superview的size是(0.0),这时仍然算作tableview没有显示到window,所以不会调用cellForRow方法。

还有很多中导致tableview没有显示到window的可能

对了在创建视图的时候记住:绝对不在init方法中创建,修改视图,哪怕是get方法加载视图

更新

检查顺序

1-代理是否设置

2-tableView的frame是否为0

3-如果使用InterfaceBuilder检查代理 IBOutlet

4-是否在主线程中reloadData  

(void) tocLoad { dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; }); }

最后附上stackoverFlow


tableView
reloadData not working



up
vote12down
votefavorite

When I call 
[tableView
reloadData]
 the function 
-
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 is not fired? Why?

Here's my TableView.m
@implementation TableView
@synthesize managedObjectContext;
@synthesize controller = _controller;
@synthesize tableView = _tableView;

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {

}
return self;
}
-(id)init
{
self = [super init];
if (self) {
NSLog(@"%s",__PRETTY_FUNCTION__);
self.del = [[UIApplication sharedApplication] delegate];
self.managedObjectContext = self.del.managedObjectContext;

[self performControllerFetch];
}
return self;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
...
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
...
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

...
}

-(void)reloadTableView
{
NSLog(@"%s",__PRETTY_FUNCTION__);

[self.tableView reloadData];

}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

NSLog(@"%s",__PRETTY_FUNCTION__);
UITableView *tableView = self.tableView;

switch(type) {

case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray
arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

switch(type) {

case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.tableView endUpdates];
}

@end


TableView.h
@interface TableView : UITableView <UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate>

@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) AppDelegate *del;
@property (nonatomic, strong) NSFetchedResultsController *controller;
@property (weak, nonatomic) IBOutlet TableView *tableView;

-(void)reloadTableView;
-(void)performControllerFetch;
@end


iphone ios objective-c uitableview
shareimprove
this question
edited Oct
10 '13 at 18:46

asked Oct 10 '13 at 17:22





iCode
9531723

 
1 
Why downvoting? – iCode Oct
10 '13 at 17:45
2 
Downvote seems a little misplaced, this is a legitimate question with what looks like some important design considerations
that the asker should be aware of. – Alfie
Hanssen Oct
10 '13 at 17:51
add
a comment


4 Answers

activeoldestvotes

up vote8down
voteaccepted
It looks like you are never setting the 
delegate
 and 
datasource
 properties
on your tableview, no? You're implementing the methods in those protocols inside 
tableview.m
 but
not setting the two properties to 
self
 hence
calling 
reloadData
 having
no effect.

Does this help?

Edit:

Looks like you have a 
tableView
 property
set on a subclass of 
UITableView
 and
hooked up to an interface builder file. This is an odd setup (a tableview within a tableview). Usually you would have something like a 
UIViewController
 subclass
hooked up to an XIB and set an

@property
(nonatomic, strong) IBOutlet UITableView * tableView


in that subclass, or something similar. And then handle the data fetching and tableview delegate/datasource inside that viewcontroller subclass.

But here, because of the nested 
UITableView
s
it's not as straightforward. Is there a reason for this design? I recommend moving to something like I describe above to help bring clarity to the setup.

Also, try adding some 
NSLog
 statements
into your 
init
 method
to see if the tableview != nil and the delegate and datasource properties have been set. My suspicion is that the connection is not being made.

Also, unrelated to the problem at hand, you no longer have to manually 
@synthesize
ivar = _ivar
, it will be done for you automatically using the underscore convention.

shareimprove
this answer
edited Oct
10 '13 at 17:47

answered Oct 10 '13 at 17:27





Alfie Hanssen
6,10743451

 
 
I've set the delegate and the datasource in the Interface Builder to the class TableView.m. Does that reach? – iCode Oct
10 '13 at 17:31
 
Hmm, Can you post the .h file as well (what class does tablview.m inherit from)? And can you post the code where you
declare your IBOutlets (if any)? Sometimes IB can be picky about whether you make the delegate/datasource connection with the "files owner" vs the view within the XIB file. – Alfie
Hanssen Oct
10 '13 at 17:35
 
I've updated my code. btw: the data in the table is displayed correctly. – iCode Oct
10 '13 at 17:38 
 
Thanks now it is working (I've done what you've suggested)! – iCode Oct
10 '13 at 18:40 
 
Aha, that's great news! – Alfie
Hanssen Oct
10 '13 at 19:00
show 1 more
comment


up vote1down
vote
Inspite of writing this 
[self.tableView
reloadData];
 try below, becuase already you have written class so no need to take the outlet again:-
[self reloadData]


shareimprove
this answer
answered Oct 10 '13 at 17:40





Hussain Shabbir
6,83131031

 
 
Still not working. – iCode Oct
10 '13 at 17:43
 
Basically what is your problem i mean it is not refreshing the data?? – Hussain
Shabbir Oct
10 '13 at 17:45
 
Yes that's the problem. – iCode Oct
10 '13 at 17:46
 
Ok do one thing disconnect you outlet,delegate and datasource of tableview and then only reconnect delegate and datasource
of your table to your controller class and check – Hussain
Shabbir Oct
10 '13 at 17:52
 
Basically that method should call when you connect delegate to the tableview – Hussain
Shabbir Oct
10 '13 at 17:53
add
a comment
up vote1down
vote
I was having the same issue, that the reload was not working. I believe the delegate method I was calling it from was in a background thread which was causing the problem. My solution was to create a new method (below) and call the reload from there instead,
while also ensuring to call it from the main thread:
(void) tocLoad { dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; }); }

shareimprove
this answer
answered Oct 15 '14 at 17:27





user3730468
711

 add
a comment
up vote0down
vote
I spent days debugging this issue, and found a ton of possible fixes. I starred the one that worked for me but they're all valid.

First, of course, check that your delegate, datasource, IBOutlet, etc are all configured properly.

**Set the All Exceptions breakpoint and see if you are getting an out of bounds exception in your datasource. Without setting the breakpoint there is no crash and the tableview will simply fail to reload.

Other possible fixes: check the tableview's frame to make sure the width or height is not 0. Try executing reloadData on the main thread. Lastly, try only reloading a single section (here).

Gotta love table views.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: