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 ()<UITableViewDataSource, UITableViewDelegate>
@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

这个例子效果如下:


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的背景色也不会变化。

tableView-2.gif

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

#import <UIKit/UIKit.h>

@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;
}

效果如下:

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;
}

效果如下:


tableView-4.gif

二. 原因

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

三.最后

送上一张图片:

图片发自简书App
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容