美文网首页
UITableView调用reloadData方法,但cellF

UITableView调用reloadData方法,但cellF

作者: 果哥爸 | 来源:发表于2017-07-28 18:06 被阅读298次

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

    滚动栏.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

    二. 原因

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

    三.最后

    送上一张图片:

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

    相关文章

      网友评论

          本文标题:UITableView调用reloadData方法,但cellF

          本文链接:https://www.haomeiwen.com/subject/cgzqhxtx.html