UITableView调用reloadData方法,但cellForRowAtIndexPath不执行

最近做这样一个需求:如下图所示,

滚动栏.gif

中间碰到了一个问题,就是 tableView 调用 reloadData方法,但是 cellForRowAtIndexPath不执行,因此记录一下。

一. 例子

//
//  ViewController.m
//  FJTestProject
//
//  Created by fjf on 2017/4/8.
//  Copyright © 2017年 fjf. All rights reserved.
//


#import "ViewController.h"


@interface ViewController ()
@property (nonatomic, strong) UITableView *tableView;
@end

@implementation ViewController


#pragma mark --- life circle

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.view addSubview:self.tableView];
    self.view.backgroundColor = [UIColor whiteColor];
}

#pragma mark --- system delegate

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 250;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellId = @"cellId";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
    }
    cell.backgroundColor = [UIColor colorWithRed:arc4random_uniform(256)/256.0 green:arc4random_uniform(256)/256.0 blue:arc4random_uniform(256)/256.0 alpha:1];
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 200;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.tableView reloadData];
}

#pragma mark --- private method
// tableView
- (UITableView *)tableView {
    if (!_tableView) {
        _tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.backgroundColor = [UIColor clearColor];
    }
    return _tableView;
}
@end

这个例子效果如下:


UITableView调用reloadData方法,但cellForRowAtIndexPath不执行_第1张图片
tableView.gif

每个cell的背景色是随机的,当点击任何一个cell会调用[self.tableView reloadData],这样每个cell的背景色就会更换。

但是当加上下面这段代码:

#pragma mark --- init method
- (instancetype)init {
   if (self = [super init]) {
        self.tableView.backgroundColor = [UIColor whiteColor];
    }
    return self;
}

再次点击cell调用[self.tableView reloadData],但不会执行- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;对应的cell的背景色也不会变化。

UITableView调用reloadData方法,但cellForRowAtIndexPath不执行_第2张图片
tableView-2.gif

同样的我们给ViewController添加一个UIColor的属性,然后通过这个属性设置self.tableView的背景色

#import 

@interface ViewController : UIViewController

@property (nonatomic, strong) UIColor *backgroudColor;
@end

#pragma mark --- setter method
- (void)setBackgroudColor:(UIColor *)backgroudColor {
    self.tableView.backgroundColor = backgroudColor;
}

然后在AppDelegate里面调用:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    ViewController *tmpViewController = [[ViewController alloc] init];
    tmpViewController.backgroudColor = [UIColor redColor];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:tmpViewController];
    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

效果如下:

UITableView调用reloadData方法,但cellForRowAtIndexPath不执行_第3张图片
tableView-3.gif

同样的,再次点击cell调用[self.tableView reloadData],但不会执行- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;对应的cell的背景色也不会变化。

也就是说只要是在- (void)viewDidLoad之前或者更确切的说是- (void)loadView之前调用self.tableView,这样就会导致调用[self.tableView reloadData],不会执行- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

所以最好保持UIViewController里面的控件的调用最好是在- (void)viewDidLoad方法里面或者之后调用。

如果非要在- (void)viewDidLoad之前或者- (void)loadView之前调用,最好先调用一下self.view这样就会保证先去调用- (void)loadView,方法这样也可以保证[self.tableView reloadData]不会受到影响。

#pragma mark --- setter method

- (void)setBackgroudColor:(UIColor *)backgroudColor {

    self.view.backgroundColor = backgroudColor;
    self.tableView.backgroundColor = backgroudColor;
}

效果如下:


UITableView调用reloadData方法,但cellForRowAtIndexPath不执行_第4张图片
tableView-4.gif

二. 原因

具体导致这个问题产生的原因,我也找了很久也没找到合理的解释,希望懂得的朋友能给出您宝贵的看法。

三.最后

送上一张图片:

UITableView调用reloadData方法,但cellForRowAtIndexPath不执行_第5张图片
图片发自App

你可能感兴趣的:(UITableView调用reloadData方法,但cellForRowAtIndexPath不执行)