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

首先是只有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

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
share improve this question
 
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

4 Answers

up vote 8 down vote accepted

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 UITableViews 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.

share improve this answer
 
 
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

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]
share improve this answer
 
 
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

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]; }); }
share improve this answer
 

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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值