viewDidLoad 和 viewWillAppear: 方法

本文探讨了iOS开发中视图控制器的viewDidLoad与viewWillAppear:方法的应用细节。通过具体案例,介绍了如何正确处理视图的初始化及更新逻辑,确保视图在不同状态下的正确显示。

每个 controller 里面一般都会实现 viewDidLoad 和 viewWillAppear: 两个方法。对于iOS开发人员来说,这两个方法都很熟悉。至少都知道前者是在初始化时被调用一次,后者是在每次这个视图要被显示之前被调用一次。因此 controller 中主要的初始化代码都放在前者中,而后者主要用于视图在显示前的更新。但现实情况并不是这么理想,因为我们在 viewDidLoad 方法中获取到一些数据并不是准确的,特别是视图相关的数据,因为很可能其他视图此时并没有完成初始化。因此只好将某些初始化工作也放到 viewWillAppear: 方法中,但是控制它只执行一次。以下用一点代码片段来举例,我的应用中有个收藏视图,使用 UITableView 做的,用户收藏的文章可以以列表形式展示在这里。当收藏为空时会展示一个带图片的提示视图,当点击这个视图任何位置时会跳转到文章目录。需求就是这样,代码片段如下。

//空白提示视图(emptyView)的初始化方法
- (void)initEmptyView {
    //emptyView 为本类的实例变量,将它的位置和大小设为与tableView一样,以便正好覆盖。这段代码如果是在 viewDidload 中被调用就会有问题,
    //获取 tableView 的尺寸信息不准,在 viewWillAppear 中被调用就没问题。
    emptyView = [[UIControl alloc] initWithFrame:self.tableView.frame];
    emptyView.backgroundColor = [UIColor clearColor];
    
    //添加一个带图片视图到 emptyView 中,并将图片视图居中
    UIImageView *noCollectImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"no_collect.png"]];
    [emptyView addSubview:noCollectImgView];
    [noCollectImgView setCenter:CGPointMake(emptyView.bounds.size.width / 2, emptyView.bounds.size.height /2)];
    
    //为 emptyView 添加点击事件
    [emptyView addTarget:self action:@selector(emptyViewClicked) forControlEvents:UIControlEventTouchUpInside];
}

//空白提示视图点击后被调用
- (void)emptyViewClicked {
    [self.tabBarController setSelectedIndex:0];
}

//空白提示视图的展示与隐藏逻辑
- (void)handleEmpty {
    if (!emptyView) {
        [self initEmptyView];
    }
    
    if (![self.tableView.superview.subviews containsObject:emptyView]) {
        [self.tableView.superview addSubview:emptyView];
    }
    
    //判断表格中是否为空
    int num = [self tableView:self.tableView numberOfRowsInSection:0];
    if (num > 0) {
        emptyView.hidden = YES;
    } else {
        emptyView.hidden = NO;
        self.navigationItem.rightBarButtonItem = nil;
    }
    
}

- (void)viewWillAppear:(BOOL)animated {
    [CoreDataContext performCollectFetch];
    [self.tableView reloadData];
    
    //空白提示视图展示与否的逻辑
    [self handleEmpty];
}



仔细分析一下,不需要超过15个,就是触发按钮后的某个环节不起作用来。 // // SDNV6SiteInsightCategoryDetailVC.m // Omada // // Created by wangchen on 2025/10/9. // Copyright © 2025 TP-Link. All rights reserved. // #import "SDNV6SiteInsightCategoryDetailVC.h" #import "SDNStaticsCategoriesDetailCell.h" #import "SDNCommonStaticCategoriesTool.h" #import "SDNInsightAppCategoriesDetailView.h" #import "TPConvTools.h" @interface SDNV6SiteInsightCategoryDetailVC () @property (nonatomic, strong) NSMutableArray <DMSDNCategoryTraffics *> *selectCategoryTrafficList; @property (nonatomic, strong) NSMutableArray <DMSDNCategoryTraffics *> *categoryTrafficList; @end @implementation SDNV6SiteInsightCategoryDetailVC - (void)viewDidLoad { [super viewDidLoad]; } - (void)tpbSetupInitialData { [super tpbSetupInitialData]; self.navigationItem.title = gMeshQuickSetup.sdnStaticsTrafficCategories; self.selectCategoryTrafficList = self.selectCategoriesInfo.categoryTraffics.mutableCopy; self.categoryTrafficList = self.categoriesInfo.categoryTraffics.mutableCopy; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self reloadView]; } - (void)reloadView { [self updateSelectCategoryTraffic]; self.sectionArray = @[[self categoriesPieChartSection],[self categoriesListSection]]; } - (TPBTableSectionModel *)categoriesListSection { TPBTableSectionModel *section = [[TPBTableSectionModel alloc] init]; NSMutableArray *cellModelArr = [[NSMutableArray alloc] init]; for (int i = 0; i < self.categoriesInfo.categoryTraffics.count; i++) { UIColor *pieColor = i < [self colorArray].count ? [self colorArray][i] : [UIColor tpbPieOther]; SDNStaticsCategoriesDetailCellModel *cellModel = [[SDNStaticsCategoriesDetailCellModel alloc] initCellModel]; cellModel.categoryTraffics = self.categoriesInfo.categoryTraffics[i]; cellModel.tintColor = pieColor; BOOL isSelected = [self isContainSelectCategoryWithFamliyId:self.categoryTrafficList[i].familyId]; TPWeakSelf cellModel.clickSelectInfo = ^{ TPStrongSelf if ([_self isContainSelectCategoryWithFamliyId:_self.categoryTrafficList[i].familyId]) { [_self.selectCategoryTrafficList removeObject:_self.categoryTrafficList[i]]; } else { [_self.selectCategoryTrafficList addObject:_self.categoryTrafficList[i]]; } [_self reloadView]; }; cellModel.isSelect = isSelected; [cellModelArr addObject:cellModel]; } section.cellModelArray = cellModelArr.copy; NSString *actionTitle = @""; if (self.selectCategoryTrafficList.count != self.categoryTrafficList.count) { actionTitle = gControllerQuickSetup.controllerQuickSetupSelectAll; } else { actionTitle = gSDNGlobal.selectNone; } TPWeakSelf TPBTableSectionViewAction *headerAction = [TPBTableSectionViewAction actionWithTitle:actionTitle actionCallback:^{ TPStrongSelf [_self clickSelectOrUnselectAll]; }]; headerAction.actionTitleColor = [UIColor tpbGreen]; section.headerTitle = gMeshQuickSetup.sdnStaticsCategories; section.headerAction = headerAction; return section; } - (void)updateSelectCategoryTraffic { self.selectCategoriesInfo.categoryTraffics = self.selectCategoryTrafficList.copy; long totalTraffic = 0; for (int i = 0; i < self.categoriesInfo.categoryTraffics.count; i++) { if ([self isContainSelectCategoryWithFamliyId:self.categoryTrafficList[i].familyId]) { totalTraffic += self.categoryTrafficList[i].traffic; } } self.selectCategoriesInfo.totalTraffic = totalTraffic; } - (TPBTableSectionModel *)categoriesPieChartSection { TPBTableSectionModel *section = [[TPBTableSectionModel alloc] init]; SDNInsightAppCategoriesDetailView *customView = [[SDNInsightAppCategoriesDetailView alloc] init]; customView.selectCategoriesInfo = self.selectCategoriesInfo; [customView updateViewWithCategoriesInfo:self.categoriesInfo]; TPBCustomViewTableCellModel *cellModel = [TPBCustomViewTableCellModel customContentWithView:customView action:nil]; section.cellModelArray = @[cellModel]; return section; } - (void)clickSelectOrUnselectAll { if (self.selectCategoryTrafficList.count != self.categoryTrafficList.count) { self.selectCategoryTrafficList = [self.categoryTrafficList mutableCopy]; } else { [self.selectCategoryTrafficList removeAllObjects]; } [self reloadView]; } - (BOOL)isContainSelectCategoryWithFamliyId:(long)famliyid { BOOL isContain = NO; for (DMSDNCategoryTraffics *category in self.selectCategoriesInfo.categoryTraffics) { if (category.familyId == famliyid) { isContain = YES; break; } } return isContain; } - (NSArray<UIColor *> *)colorArray { NSMutableArray *colorMuArray = [[NSMutableArray alloc] init]; [colorMuArray addObject:[UIColor tpbPie1]]; [colorMuArray addObject:[UIColor tpbPie2]]; [colorMuArray addObject:[UIColor tpbPie3]]; [colorMuArray addObject:[UIColor tpbPie4]]; [colorMuArray addObject:[UIColor tpbPie5]]; [colorMuArray addObject:[UIColor tpbPie6]]; [colorMuArray addObject:[UIColor tpbPie7]]; [colorMuArray addObject:[UIColor tpbPie8]]; [colorMuArray addObject:[UIColor tpbPie9]]; [colorMuArray addObject:[UIColor tpbPie10]]; [colorMuArray addObject:[UIColor tpbPie11]]; [colorMuArray addObject:[UIColor tpbPie12]]; [colorMuArray addObject:[UIColor tpbPie13]]; [colorMuArray addObject:[UIColor tpbPie14]]; [colorMuArray addObject:[UIColor tpbPie15]]; return [colorMuArray copy]; } @end 错误在这里,错误发生时,没有执行下面函数,导致removeObject没有发生,因为页面没有变化 TPStrongSelf if ([_self isContainSelectCategoryWithFamliyId:_self.categoryTrafficList[i].familyId]) { [_self.selectCategoryTrafficList removeObject:_self.categoryTrafficList[i]]; } else { [_self.selectCategoryTrafficList addObject:_self.categoryTrafficList[i]]; } [_self reloadView];
最新发布
11-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值