dequeueReusableCellWithIdentifier

本文详细介绍了UITableView如何使用dequeueReusableCellWithIdentifier方法来提高性能。通过重用UITableViewCell对象,避免了不必要的对象创建,从而提升了应用程序效率。

dequeueReusableCellWithIdentifier:

Returns a reusable table-view cell object located by its identifier.

- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier

Parameters
identifier

A string identifying the cell object to be reused. By default, a reusable cell’s identifier is its class name, but you can change it to any arbitrary value.

Return Value

UITableViewCell object with the associated identifier or nil if no such object exists in the reusable-cell queue.

Discussion

For performance reasons, a table view’s data source should generally reuseUITableViewCell objects when it assigns cells to rows in itstableView:cellForRowAtIndexPath: method. A table view maintains a queue or list ofUITableViewCell objects that the table view’s delegate has marked for reuse. It marks a cell for reuse by assigning it a reuse identifier when it creates it (that is, in theinitWithFrame:reuseIdentifier: method of UITableViewCell). The data source can access specific “template” cell objects in this queue by invoking thedequeueReusableCellWithIdentifier: method. You can access a cell’s reuse identifier through its reuseIdentifier property, which is defined by UITableViewCell.

Availability
  • Available in iPhone OS 2.0 and later.
Related Sample Code
Declared In
UITableView.h

好好检查一下,另外我在发给你父类的m文件参考 @interface TPBCommonTableController () < TPBTableCommonInputDelegate, TPBTableListInputDelegate > @property (nonatomic, assign) UITableViewStyle tableViewStyle; @property (nonatomic, strong) UIView *tpbSearchBarPlaceholderView; @property (nonatomic, strong) TPBTableSearchHeader *tpbInnerSearchBar; @property (nonatomic, strong) TPBEmptyView *emptyView; @property (nonatomic, strong) TPKeyboardAvoidingTableView *tableView; @property (nonatomic, strong) MASConstraint *emptyCenterYConstraint; @property (nonatomic, strong) MASConstraint *searchBarTopConstraint; @property (nonatomic, strong) MASConstraint *searchBarHeightConstraint; @end @implementation TPBCommonTableController - (instancetype)init { if (@available(iOS 13.0, *)) { return [self initWithTableViewStyle:UITableViewStyleInsetGrouped]; } else { return [self initWithTableViewStyle:UITableViewStyleGrouped]; } } - (instancetype)initWithTableViewStyle:(UITableViewStyle)style { if (self = [super initWithNibName:nil bundle:nil]) { _tableViewStyle = style; _hideCellSeparator = NO; } return self; } - (instancetype)initWithCoder:(NSCoder *)coder { if (self = [super initWithCoder:coder]) { UITableViewStyle style = UITableViewStyleGrouped; if (@available(iOS 13.0, *)) { style = UITableViewStyleInsetGrouped; } _tableViewStyle = style; _hideCellSeparator = NO; } return self; } - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { UITableViewStyle style = UITableViewStyleGrouped; if (@available(iOS 13.0, *)) { style = UITableViewStyleInsetGrouped; } _tableViewStyle = style; _hideCellSeparator = NO; } return self; } - (void)dealloc { [self.view tpbRemoveForKeyboardEvent]; } - (void)tpbSetupInitialData { [super tpbSetupInitialData]; self.keyboardBehavior = TPBCommonTableKeyboardBehaviorDismissOnly; } - (void)tpbSetupSubviews { [super tpbSetupSubviews]; [self.tableView insertSubview:self.emptyView atIndex:0]; [self.view addSubview:self.tableView]; [self.view addSubview:self.tpbInnerSearchBar]; } - (void)tpbMakeConstraint { [super tpbMakeConstraint]; [self.emptyView mas_remakeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.equalTo(self.mas_tpSafeAreaLayoutGuide); self.emptyCenterYConstraint = make.centerY.equalTo(self.mas_tpSafeAreaLayoutGuide); }]; [self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mas_tpSafeAreaLayoutGuide); make.leading.trailing.equalTo(self.mas_tpSafeAreaLayoutGuide); make.bottom.equalTo(self.view); }]; CGFloat searchHeight = [self.tpbInnerSearchBar preferredHeight]; [self.tpbInnerSearchBar mas_remakeConstraints:^(MASConstraintMaker *make) { self.searchBarTopConstraint = make.top.equalTo(self.mas_tpSafeAreaLayoutGuide).offset(0); make.leading.trailing.equalTo(self.mas_tpSafeAreaLayoutGuide); self.searchBarHeightConstraint = make.height.equalTo(@(searchHeight)); }]; } - (void)tpbBindActions { [super tpbBindActions]; TPBWeakSelf [self tpbAddContentSizeDidChangeConfig:^(id _Nonnull object, TPBDynamicContentManager * _Nonnull manager) { TPBStrongSelf dispatch_async(dispatch_get_main_queue(), ^{ [_self updateTableHeader]; [_self.tableView reloadData]; }); } notifyWhenRegister:NO]; } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; [self.view bringSubviewToFront:self.tpbInnerSearchBar]; [self updateSearchBarPosition]; } #pragma mark - Public - (void)setSectionArray:(NSArray<TPBTableSectionModel *> *)sectionArray { _sectionArray = sectionArray; [self.tableView reloadData]; } - (void)setSearchBarShow:(BOOL)searchBarShow { _searchBarShow = searchBarShow; self.tpbInnerSearchBar.hidden = !searchBarShow; [self updateTableHeader]; } - (NSString *)searchPlaceholder { return self.tpbInnerSearchBar.searchPlaceholder; } - (void)setSearchPlaceholder:(NSString *)searchPlaceholder { self.tpbInnerSearchBar.searchPlaceholder = searchPlaceholder; } - (void)updateSearchKey:(NSString *)searchKey { [self.tpbInnerSearchBar updateSearchKey:searchKey]; } - (void)setCustomTableHeaderView:(UIView *)customTableHeaderView { _customTableHeaderView = customTableHeaderView; [self updateTableHeader]; } - (void)setKeyboardBehavior:(TPBCommonTableKeyboardBehavior)keyboardBehavior { _keyboardBehavior = keyboardBehavior; switch (keyboardBehavior) { case TPBCommonTableKeyboardBehaviorDismissOnly: [self.view tpbRegisterForKeyboardEvent]; break; case TPBCommonTableKeyboardBehaviorDismissAndRespondClick: [self.view tpbRemoveForKeyboardEvent]; break; default: break; } } - (void)focusToFirstEligibleElement { NSIndexPath *indexPath = nil; for (NSUInteger section = 0; section < self.sectionArray.count; section++) { TPBTableSectionModel *sectionModel = self.sectionArray[section]; for (NSUInteger row = 0; row < sectionModel.cellModelArray.count; row++) { TPBBaseTableCellModel *cellModel = sectionModel.cellModelArray[row]; if (cellModel.isAutoFocusEnabled) { indexPath = [NSIndexPath indexPathForRow:row inSection:section]; break; } } if (indexPath != nil) break; } if (indexPath == nil) return; UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; if (cell == nil) return; if ([TPBA11yHelper isVoiceOverOn]) { UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, cell); } else { [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; } } #pragma mark - UITableViewDataSource & UITableViewDelegate // 注册自定义Cell - (void)registerCustomCellWithCellModel:(TPBCustomTableCellBaseModel *)customCellModel tableView:(UITableView *)tableView cellIdentifier:(NSString *)cellIdentifier { if (customCellModel.cellClass != nil) { BOOL isCellClassValid = [customCellModel.cellClass isSubclassOfClass:[UITableViewCell class]]; BOOL isValid = isCellClassValid; NSAssert(isCellClassValid, @"TPBCustomBaseTableCellModel's cellClass「%@」is not Subclass of UITableViewCell!", NSStringFromClass(customCellModel.cellClass)); if (!isValid) { return; } // 注册Cell Class [tableView registerClass:customCellModel.cellClass forCellReuseIdentifier:cellIdentifier]; } else if (customCellModel.cellNib != nil) { // 注册Cell Nib [tableView registerNib:customCellModel.cellNib forCellReuseIdentifier:cellIdentifier]; } } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return self.sectionArray.count; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return 0; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; return sectionModel.cellModelArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section < 0 || self.sectionArray.count <= indexPath.section) { return [[UITableViewCell alloc] init]; } TPBTableSectionModel *sectionModel = self.sectionArray[indexPath.section]; if (indexPath.row < 0 || sectionModel.cellModelArray.count <= indexPath.row) { return [[UITableViewCell alloc] init]; } BOOL isRTL = self.view.effectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft; BOOL isLast = indexPath.row == sectionModel.cellModelArray.count - 1; TPBBaseTableCellModel *model = sectionModel.cellModelArray[indexPath.row]; switch (model.cellType) { case TPBTableCellTypeCustomCell: { if ([model isKindOfClass:[TPBCustomTableCellBaseModel class]]) { TPBCustomTableCellBaseModel *cellModel = (TPBCustomTableCellBaseModel *)model; NSString *cellIdentifier = [cellModel effectiveCellIdentifier:isRTL]; UITableViewCell *cell; if (TPBA11yHelper.isVoiceOverOn && cellModel.cellClass != nil) { cell = [[cellModel.cellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } if (cell == nil) { // 若无法获取Cell,说明可能是未注册自定义Cell,则注册自定义Cell之后尝试重新取值 [self registerCustomCellWithCellModel:cellModel tableView:tableView cellIdentifier:cellIdentifier]; cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } if (cellModel.cellConfigCallback) { cellModel.cellConfigCallback(tableView, indexPath, cell, cellModel); } if ([cell isKindOfClass:[TPBBaseTableViewCell class]]) { TPBBaseTableViewCell *baseCell = (TPBBaseTableViewCell *)cell; [baseCell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; } return cell; } } break; case TPBTableCellTypeCustomView: { if ([model isKindOfClass:[TPBCustomViewTableCellModel class]]) { TPBCustomViewTableCellModel *cellModel = (TPBCustomViewTableCellModel *)model; NSString *cellIdentifier = [TPBCustomViewTableCell cellIdentifier:isRTL]; TPBCustomViewTableCell *cell; cell = [[TPBCustomViewTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeTitleSubtitle: { if ([model isKindOfClass:[TPBTitleSubtitleTableCellModel class]]) { TPBTitleSubtitleTableCellModel *cellModel = (TPBTitleSubtitleTableCellModel *)model; NSString *cellIdentifier = [TPBTitleSubtitleTableCell cellIdentifier:isRTL]; TPBTitleSubtitleTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBTitleSubtitleTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeSwitch: { if ([model isKindOfClass:[TPBSwitchTableCellModel class]]) { TPBSwitchTableCellModel *cellModel = (TPBSwitchTableCellModel *)model; NSString *cellIdentifier = [TPBSwitchTableCell cellIdentifier:isRTL]; TPBSwitchTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBSwitchTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeListButton: { if ([model isKindOfClass:[TPBListButtonTableCellModel class]]) { TPBListButtonTableCellModel *cellModel = (TPBListButtonTableCellModel *)model; NSString *cellIdentifier = [TPBListButtonTableCell cellIdentifier:isRTL]; TPBListButtonTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBListButtonTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeProgress: { if ([model isKindOfClass:[TPBProgressTableCellModel class]]) { TPBProgressTableCellModel *cellModel = (TPBProgressTableCellModel *)model; NSString *cellIdentifier = [TPBProgressTableCell cellIdentifier:isRTL]; TPBProgressTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBProgressTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeCommonInput: { if ([model isKindOfClass:[TPBCommonInputTableCellModel class]]) { TPBCommonInputTableCellModel *cellModel = (TPBCommonInputTableCellModel *)model; NSString *cellIdentifier = [TPBCommonInputTableCell cellIdentifier:isRTL]; TPBCommonInputTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBCommonInputTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } cell.inputDelegate = self; [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeCheck: { if ([model isKindOfClass:[TPBCheckTableCellModel class]]) { TPBCheckTableCellModel *cellModel = (TPBCheckTableCellModel *)model; BOOL isCustomizedCellHeight = cellModel.height.isCustomHeight; NSString *cellIdentifier = [TPBCheckTableCell cellIdentifier:isRTL]; TPBCheckTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBCheckTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel isCustomizedCellHeight:isCustomizedCellHeight]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeJumpSelect: { if ([model isKindOfClass:[TPBJumpSelectTableCellModel class]]) { TPBJumpSelectTableCellModel *cellModel = (TPBJumpSelectTableCellModel *)model; NSString *cellIdentifier = [TPBJumpSelectTableCell cellIdentifier:isRTL]; TPBJumpSelectTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBJumpSelectTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && TPBIsEmptyString(cellModel.title) && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeMenuSelect: { if ([model isKindOfClass:[TPBMenuSelectTableCellModel class]]) { TPBMenuSelectTableCellModel *cellModel = (TPBMenuSelectTableCellModel *)model; NSString *cellIdentifier = [TPBMenuSelectTableCell cellIdentifier:isRTL]; TPBMenuSelectTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBMenuSelectTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeListInput: { if ([model isKindOfClass:[TPBListInputTableCellModel class]]) { TPBListInputTableCellModel *cellModel = (TPBListInputTableCellModel *)model; NSString *cellIdentifier = [TPBListInputTableCell cellIdentifier:isRTL]; TPBListInputTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBListInputTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } cell.inputDelegate = self; [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeTitleAction: { if ([model isKindOfClass:[TPBTitleActionTableCellModel class]]) { TPBTitleActionTableCellModel *cellModel = (TPBTitleActionTableCellModel *)model; NSString *cellIdentifier = [TPBTitleActionTableCell cellIdentifier:isRTL]; TPBTitleActionTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBTitleActionTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; } return [[UITableViewCell alloc] init]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section < 0 || self.sectionArray.count <= indexPath.section) { return UITableViewAutomaticDimension; } TPBTableSectionModel *sectionModel = self.sectionArray[indexPath.section]; if (indexPath.row < 0 || sectionModel.cellModelArray.count <= indexPath.row) { return UITableViewAutomaticDimension; } TPBBaseTableCellModel *cellModel = sectionModel.cellModelArray[indexPath.row]; if (cellModel.height.isCustomHeight) { return cellModel.height.customHeight; } return UITableViewAutomaticDimension; } // Header - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return [UIView new]; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; if (sectionModel.customHeaderView != nil) { return sectionModel.customHeaderView; } if (TPBIsEmptyString(sectionModel.headerTitle) && sectionModel.headerAction == nil) { return [UIView new]; } TPBTableTextSectionHeader *headerView = [TPBTableTextSectionHeader new]; [headerView updateSectionModel:sectionModel]; return headerView; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return TPBDesign.list.sectionHeaderHeight; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; if (sectionModel.sectionHeaderHeight.isCustomHeight) { return sectionModel.sectionHeaderHeight.customHeight; } if (sectionModel.customHeaderView != nil) { return UITableViewAutomaticDimension; } if (TPBIsEmptyString(sectionModel.headerTitle) && sectionModel.headerAction == nil) { if (self.searchBarShow && section == 0) { return 10; } return TPBDesign.list.sectionHeaderHeight; } return UITableViewAutomaticDimension; } // Footer - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return [UIView new]; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; if (sectionModel.customFooterView != nil) { return sectionModel.customFooterView; } if (TPBIsEmptyString(sectionModel.footerTitle) && sectionModel.footerAction == nil) { return [UIView new]; } TPBTableTextSectionFooter *footerView = [TPBTableTextSectionFooter new]; [footerView updateSectionModel:sectionModel]; return footerView; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return TPBDesign.list.sectionFooterHeight; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; if (sectionModel.sectionFooterHeight.isCustomHeight) { return sectionModel.sectionFooterHeight.customHeight; } if (sectionModel.customFooterView != nil) { return UITableViewAutomaticDimension; } if (TPBIsEmptyString(sectionModel.footerTitle) && sectionModel.footerAction == nil) { return TPBDesign.list.sectionFooterHeight; } return UITableViewAutomaticDimension; } // TableViewCell点击 - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:NO]; if (indexPath.section < 0 || self.sectionArray.count <= indexPath.section) { return NO; } TPBTableSectionModel *sectionModel = self.sectionArray[indexPath.section]; if (indexPath.row < 0 || sectionModel.cellModelArray.count <= indexPath.row) { return NO; } TPBBaseTableCellModel *cellModel = sectionModel.cellModelArray[indexPath.row]; switch (cellModel.cellType) { case TPBTableCellTypeCustomCell: case TPBTableCellTypeCustomView: case TPBTableCellTypeTitleSubtitle: case TPBTableCellTypeSwitch: case TPBTableCellTypeCheck: case TPBTableCellTypeListButton: case TPBTableCellTypeJumpSelect: case TPBTableCellTypeMenuSelect: case TPBTableCellTypeProgress: case TPBTableCellTypeTitleAction: return YES; case TPBTableCellTypeCommonInput: case TPBTableCellTypeListInput: return NO; } } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:NO]; if (indexPath.section < 0 || self.sectionArray.count <= indexPath.section) { return; } TPBTableSectionModel *sectionModel = self.sectionArray[indexPath.section]; if (indexPath.row < 0 || sectionModel.cellModelArray.count <= indexPath.row) { return; } if (self.keyboardBehavior == TPBCommonTableKeyboardBehaviorDismissAndRespondClick) { [self tpbHideKeyboard]; } TPBBaseTableCellModel *model = sectionModel.cellModelArray[indexPath.row]; switch (model.cellType) { case TPBTableCellTypeCustomCell: { if ([model isKindOfClass:[TPBCustomTableCellBaseModel class]]) { TPBCustomTableCellBaseModel *cellModel = (TPBCustomTableCellBaseModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeCustomView: { if ([model isKindOfClass:[TPBCustomViewTableCellModel class]]) { TPBCustomViewTableCellModel *cellModel = (TPBCustomViewTableCellModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeTitleSubtitle: { if ([model isKindOfClass:[TPBTitleSubtitleTableCellModel class]]) { TPBTitleSubtitleTableCellModel *cellModel = (TPBTitleSubtitleTableCellModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeSwitch: { if ([model isKindOfClass:[TPBSwitchTableCellModel class]]) { TPBSwitchTableCellModel *cellModel = (TPBSwitchTableCellModel *)model; if (cellModel.switchDidClickHotZoneCallback) { cellModel.switchDidClickHotZoneCallback(); } } } break; case TPBTableCellTypeListButton: { if ([model isKindOfClass:[TPBListButtonTableCellModel class]]) { TPBListButtonTableCellModel *cellModel = (TPBListButtonTableCellModel *)model; if (cellModel.actionEnabled && cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeCheck: { if ([model isKindOfClass:[TPBCheckTableCellModel class]]) { TPBCheckTableCellModel *cellModel = (TPBCheckTableCellModel *)model; if (cellModel.checkEnabled && cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeJumpSelect: { if ([model isKindOfClass:[TPBJumpSelectTableCellModel class]]) { TPBJumpSelectTableCellModel *cellModel = (TPBJumpSelectTableCellModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } case TPBTableCellTypeTitleAction: { if ([model isKindOfClass:[TPBTitleActionTableCellModel class]]) { TPBTitleActionTableCellModel *cellModel = (TPBTitleActionTableCellModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeMenuSelect: break; case TPBTableCellTypeProgress: case TPBTableCellTypeCommonInput: case TPBTableCellTypeListInput: break; } } //- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{ // if (indexPath.row < 0 || indexPath.row >= self.cloudDeviceList.count) { // return NO; // } // TPBDMECDevice *ecDevice = self.cloudDeviceList[indexPath.row]; // return [self canForgetWithDevice:ecDevice]; //} //- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { // if (indexPath.row < 0 || indexPath.row >= self.cloudDeviceList.count) { // return @[]; // } // TPBDMECDevice *ecDevice = self.cloudDeviceList[indexPath.row]; // TPBWeakSelf; // UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:gControllerCloudAccess.controllerCloudAccessForget handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){ // TPBStrongSelf; // [_self popAlertControlForUnbindActionWithECDevice:ecDevice]; // }]; // deleteAction.backgroundColor = [UIColor tpbRed]; // return @[deleteAction]; //} #pragma mark - UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView { [self updateSearchBarPosition]; } #pragma mark - TPBTableSearchHeaderDelegate - (void)tpbTableSearchHeaderHideKeyboard { [self tpbHideKeyboard]; } #pragma mark - TPBTableCommonInputDelegate - (void)tableCommonInputFieldDidClickReturn:(TPBCommonInputView *)inputView textField:(UITextField *)textField { [self handleUserClickReturnForTextField:textField]; } #pragma mark - TPBTableListInputDelegate - (void)tableListInputFieldDidClickReturn:(TPBListInputTableCell *)inputCell textField:(UITextField *)textField { [self handleUserClickReturnForTextField:textField]; } #pragma mark - Private - (void)updateSearchBarPosition { CGFloat tableY = self.tableView.frame.origin.y; CGRect convertedRect = [self.tpbSearchBarPlaceholderView convertRect:self.tpbSearchBarPlaceholderView.bounds toView:self.view]; CGFloat diffY = convertedRect.origin.y - tableY; CGFloat targetConstant = MAX(0, diffY); if (self.searchBarTopConstraint.tpbConstant != targetConstant) { self.searchBarTopConstraint.tpbConstant = targetConstant; } } // 用户点击UITextField键盘Return - (void)handleUserClickReturnForTextField:(UITextField *)textField { if (textField.returnKeyType != UIReturnKeyNext) { [textField resignFirstResponder]; return; } if ([self.tableView focusNextTextField]) { } else { [textField resignFirstResponder]; } } - (void)updateTableHeader { if (self.searchBarShow) { CGFloat searchBarHeight = [self.tpbInnerSearchBar preferredHeight]; self.tpbSearchBarPlaceholderView.frame = CGRectMake(0, 0, self.view.bounds.size.width, searchBarHeight); self.tableView.tableHeaderView = self.tpbSearchBarPlaceholderView; self.searchBarHeightConstraint.tpbConstant = searchBarHeight; } else if (self.customTableHeaderView) { self.tableView.tableHeaderView = self.customTableHeaderView; } else { UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, CGFLOAT_MIN)]; self.tableView.tableHeaderView = view; } } #pragma mark - Property - (TPBEmptyView *)emptyView { if (!_emptyView) { _emptyView = [TPBEmptyView new]; _emptyView.hidden = YES; } return _emptyView; } - (UIView *)tpbSearchBarPlaceholderView { if (!_tpbSearchBarPlaceholderView) { _tpbSearchBarPlaceholderView = [UIView new]; } return _tpbSearchBarPlaceholderView; } - (TPBTableSearchHeader *)tpbInnerSearchBar { if (!_tpbInnerSearchBar) { CGRect frame = CGRectMake(0, 0, self.view.bounds.size.width, 62); _tpbInnerSearchBar = [[TPBTableSearchHeader alloc] initWithFrame:frame]; _tpbInnerSearchBar.delegate = self; _tpbInnerSearchBar.hidden = YES; _tpbInnerSearchBar.backgroundColor = [UIColor tpbBackground]; } return _tpbInnerSearchBar; } - (UITableView *)tableView { if (!_tableView) { _tableView = [[TPKeyboardAvoidingTableView alloc] initWithFrame:CGRectZero style:self.tableViewStyle]; if (@available(iOS 13.0, *)) { _tableView.automaticallyAdjustsScrollIndicatorInsets = YES; } if (@available(iOS 15.0, *)) { UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, CGFLOAT_MIN)]; _tableView.tableHeaderView = view; _tableView.sectionHeaderTopPadding = 0; } _tableView.backgroundColor = [UIColor clearColor]; _tableView.estimatedRowHeight = 72; _tableView.estimatedSectionHeaderHeight = 68; _tableView.showsHorizontalScrollIndicator = NO; _tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.sectionIndexColor = [UIColor tpbTableSectionIndexColor]; _tableView.delegate = self; _tableView.dataSource = self; NSArray<Class> *cellClassArray = @[ [TPBCustomViewTableCell class], [TPBTitleSubtitleTableCell class], [TPBSwitchTableCell class], [TPBProgressTableCell class], [TPBCommonInputTableCell class], [TPBCheckTableCell class], [TPBJumpSelectTableCell class], [TPBMenuSelectTableCell class], [TPBListInputTableCell class], [TPBListButtonTableCell class], [TPBTitleActionTableCell class] ]; for (Class cls in cellClassArray) { if ([cls isSubclassOfClass:[TPBBaseTableViewCell class]]) { NSString *cellIdentifier = [cls cellIdentifier]; [_tableView registerClass:cls forCellReuseIdentifier:cellIdentifier]; NSString *rtlCellIdentifier = [cls cellIdentifier:YES]; [_tableView registerClass:cls forCellReuseIdentifier:rtlCellIdentifier]; NSString *ltrCellIdentifier = [cls cellIdentifier:NO]; [_tableView registerClass:cls forCellReuseIdentifier:ltrCellIdentifier]; } } } return _tableView; } @end
最新发布
12-03
这里是m文件 应该是这里面具体写了吧 #import "TPBCommonTableController.h" #import "TPBTableTextSectionHeader.h" #import "TPBTableTextSectionFooter.h" #import "TPBDesignKit.h" #import "UIView+TPBExpanded.h" #import "MASConstraint+TPBExpanded.h" #import "TPBTableSectionModel.h" #import "TPBCommonInputView.h" #import "TPBCustomTableCellBaseModel.h" #import "TPBCustomViewTableCell.h" #import "TPBTitleSubtitleTableCell.h" #import "TPBSwitchTableCell.h" #import "TPBListButtonTableCell.h" #import "TPBProgressTableCell.h" #import "TPBCommonInputTableCell.h" #import "TPBCheckTableCell.h" #import "TPBJumpSelectTableCell.h" #import "TPBMenuSelectTableCell.h" #import "TPBListInputTableCell.h" #import "TPBTitleActionTableCell.h" @interface TPBCommonTableController () < TPBTableCommonInputDelegate, TPBTableListInputDelegate > @property (nonatomic, assign) UITableViewStyle tableViewStyle; @property (nonatomic, strong) UIView *tpbSearchBarPlaceholderView; @property (nonatomic, strong) TPBTableSearchHeader *tpbInnerSearchBar; @property (nonatomic, strong) TPBEmptyView *emptyView; @property (nonatomic, strong) TPKeyboardAvoidingTableView *tableView; @property (nonatomic, strong) MASConstraint *emptyCenterYConstraint; @property (nonatomic, strong) MASConstraint *searchBarTopConstraint; @property (nonatomic, strong) MASConstraint *searchBarHeightConstraint; @end @implementation TPBCommonTableController - (instancetype)init { if (@available(iOS 13.0, *)) { return [self initWithTableViewStyle:UITableViewStyleInsetGrouped]; } else { return [self initWithTableViewStyle:UITableViewStyleGrouped]; } } - (instancetype)initWithTableViewStyle:(UITableViewStyle)style { if (self = [super initWithNibName:nil bundle:nil]) { _tableViewStyle = style; _hideCellSeparator = NO; } return self; } - (instancetype)initWithCoder:(NSCoder *)coder { if (self = [super initWithCoder:coder]) { UITableViewStyle style = UITableViewStyleGrouped; if (@available(iOS 13.0, *)) { style = UITableViewStyleInsetGrouped; } _tableViewStyle = style; _hideCellSeparator = NO; } return self; } - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { UITableViewStyle style = UITableViewStyleGrouped; if (@available(iOS 13.0, *)) { style = UITableViewStyleInsetGrouped; } _tableViewStyle = style; _hideCellSeparator = NO; } return self; } - (void)dealloc { [self.view tpbRemoveForKeyboardEvent]; } - (void)tpbSetupInitialData { [super tpbSetupInitialData]; self.keyboardBehavior = TPBCommonTableKeyboardBehaviorDismissOnly; } - (void)tpbSetupSubviews { [super tpbSetupSubviews]; [self.tableView insertSubview:self.emptyView atIndex:0]; [self.view addSubview:self.tableView]; [self.view addSubview:self.tpbInnerSearchBar]; } - (void)tpbMakeConstraint { [super tpbMakeConstraint]; [self.emptyView mas_remakeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.equalTo(self.mas_tpSafeAreaLayoutGuide); self.emptyCenterYConstraint = make.centerY.equalTo(self.mas_tpSafeAreaLayoutGuide); }]; [self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mas_tpSafeAreaLayoutGuide); make.leading.trailing.equalTo(self.mas_tpSafeAreaLayoutGuide); make.bottom.equalTo(self.view); }]; CGFloat searchHeight = [self.tpbInnerSearchBar preferredHeight]; [self.tpbInnerSearchBar mas_remakeConstraints:^(MASConstraintMaker *make) { self.searchBarTopConstraint = make.top.equalTo(self.mas_tpSafeAreaLayoutGuide).offset(0); make.leading.trailing.equalTo(self.mas_tpSafeAreaLayoutGuide); self.searchBarHeightConstraint = make.height.equalTo(@(searchHeight)); }]; } - (void)tpbBindActions { [super tpbBindActions]; TPBWeakSelf [self tpbAddContentSizeDidChangeConfig:^(id _Nonnull object, TPBDynamicContentManager * _Nonnull manager) { TPBStrongSelf dispatch_async(dispatch_get_main_queue(), ^{ [_self updateTableHeader]; [_self.tableView reloadData]; }); } notifyWhenRegister:NO]; } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; [self.view bringSubviewToFront:self.tpbInnerSearchBar]; [self updateSearchBarPosition]; } #pragma mark - Public - (void)setSectionArray:(NSArray<TPBTableSectionModel *> *)sectionArray { _sectionArray = sectionArray; [self.tableView reloadData]; } - (void)setSearchBarShow:(BOOL)searchBarShow { _searchBarShow = searchBarShow; self.tpbInnerSearchBar.hidden = !searchBarShow; [self updateTableHeader]; } - (NSString *)searchPlaceholder { return self.tpbInnerSearchBar.searchPlaceholder; } - (void)setSearchPlaceholder:(NSString *)searchPlaceholder { self.tpbInnerSearchBar.searchPlaceholder = searchPlaceholder; } - (void)updateSearchKey:(NSString *)searchKey { [self.tpbInnerSearchBar updateSearchKey:searchKey]; } - (void)setCustomTableHeaderView:(UIView *)customTableHeaderView { _customTableHeaderView = customTableHeaderView; [self updateTableHeader]; } - (void)setKeyboardBehavior:(TPBCommonTableKeyboardBehavior)keyboardBehavior { _keyboardBehavior = keyboardBehavior; switch (keyboardBehavior) { case TPBCommonTableKeyboardBehaviorDismissOnly: [self.view tpbRegisterForKeyboardEvent]; break; case TPBCommonTableKeyboardBehaviorDismissAndRespondClick: [self.view tpbRemoveForKeyboardEvent]; break; default: break; } } - (void)focusToFirstEligibleElement { NSIndexPath *indexPath = nil; for (NSUInteger section = 0; section < self.sectionArray.count; section++) { TPBTableSectionModel *sectionModel = self.sectionArray[section]; for (NSUInteger row = 0; row < sectionModel.cellModelArray.count; row++) { TPBBaseTableCellModel *cellModel = sectionModel.cellModelArray[row]; if (cellModel.isAutoFocusEnabled) { indexPath = [NSIndexPath indexPathForRow:row inSection:section]; break; } } if (indexPath != nil) break; } if (indexPath == nil) return; UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; if (cell == nil) return; if ([TPBA11yHelper isVoiceOverOn]) { UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, cell); } else { [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; } } #pragma mark - UITableViewDataSource & UITableViewDelegate // 注册自定义Cell - (void)registerCustomCellWithCellModel:(TPBCustomTableCellBaseModel *)customCellModel tableView:(UITableView *)tableView cellIdentifier:(NSString *)cellIdentifier { if (customCellModel.cellClass != nil) { BOOL isCellClassValid = [customCellModel.cellClass isSubclassOfClass:[UITableViewCell class]]; BOOL isValid = isCellClassValid; NSAssert(isCellClassValid, @"TPBCustomBaseTableCellModel's cellClass「%@」is not Subclass of UITableViewCell!", NSStringFromClass(customCellModel.cellClass)); if (!isValid) { return; } // 注册Cell Class [tableView registerClass:customCellModel.cellClass forCellReuseIdentifier:cellIdentifier]; } else if (customCellModel.cellNib != nil) { // 注册Cell Nib [tableView registerNib:customCellModel.cellNib forCellReuseIdentifier:cellIdentifier]; } } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return self.sectionArray.count; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return 0; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; return sectionModel.cellModelArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section < 0 || self.sectionArray.count <= indexPath.section) { return [[UITableViewCell alloc] init]; } TPBTableSectionModel *sectionModel = self.sectionArray[indexPath.section]; if (indexPath.row < 0 || sectionModel.cellModelArray.count <= indexPath.row) { return [[UITableViewCell alloc] init]; } BOOL isRTL = self.view.effectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft; BOOL isLast = indexPath.row == sectionModel.cellModelArray.count - 1; TPBBaseTableCellModel *model = sectionModel.cellModelArray[indexPath.row]; switch (model.cellType) { case TPBTableCellTypeCustomCell: { if ([model isKindOfClass:[TPBCustomTableCellBaseModel class]]) { TPBCustomTableCellBaseModel *cellModel = (TPBCustomTableCellBaseModel *)model; NSString *cellIdentifier = [cellModel effectiveCellIdentifier:isRTL]; UITableViewCell *cell; if (TPBA11yHelper.isVoiceOverOn && cellModel.cellClass != nil) { cell = [[cellModel.cellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } if (cell == nil) { // 若无法获取Cell,说明可能是未注册自定义Cell,则注册自定义Cell之后尝试重新取值 [self registerCustomCellWithCellModel:cellModel tableView:tableView cellIdentifier:cellIdentifier]; cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } if (cellModel.cellConfigCallback) { cellModel.cellConfigCallback(tableView, indexPath, cell, cellModel); } if ([cell isKindOfClass:[TPBBaseTableViewCell class]]) { TPBBaseTableViewCell *baseCell = (TPBBaseTableViewCell *)cell; [baseCell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; } return cell; } } break; case TPBTableCellTypeCustomView: { if ([model isKindOfClass:[TPBCustomViewTableCellModel class]]) { TPBCustomViewTableCellModel *cellModel = (TPBCustomViewTableCellModel *)model; NSString *cellIdentifier = [TPBCustomViewTableCell cellIdentifier:isRTL]; TPBCustomViewTableCell *cell; cell = [[TPBCustomViewTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeTitleSubtitle: { if ([model isKindOfClass:[TPBTitleSubtitleTableCellModel class]]) { TPBTitleSubtitleTableCellModel *cellModel = (TPBTitleSubtitleTableCellModel *)model; NSString *cellIdentifier = [TPBTitleSubtitleTableCell cellIdentifier:isRTL]; TPBTitleSubtitleTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBTitleSubtitleTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeSwitch: { if ([model isKindOfClass:[TPBSwitchTableCellModel class]]) { TPBSwitchTableCellModel *cellModel = (TPBSwitchTableCellModel *)model; NSString *cellIdentifier = [TPBSwitchTableCell cellIdentifier:isRTL]; TPBSwitchTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBSwitchTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeListButton: { if ([model isKindOfClass:[TPBListButtonTableCellModel class]]) { TPBListButtonTableCellModel *cellModel = (TPBListButtonTableCellModel *)model; NSString *cellIdentifier = [TPBListButtonTableCell cellIdentifier:isRTL]; TPBListButtonTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBListButtonTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeProgress: { if ([model isKindOfClass:[TPBProgressTableCellModel class]]) { TPBProgressTableCellModel *cellModel = (TPBProgressTableCellModel *)model; NSString *cellIdentifier = [TPBProgressTableCell cellIdentifier:isRTL]; TPBProgressTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBProgressTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeCommonInput: { if ([model isKindOfClass:[TPBCommonInputTableCellModel class]]) { TPBCommonInputTableCellModel *cellModel = (TPBCommonInputTableCellModel *)model; NSString *cellIdentifier = [TPBCommonInputTableCell cellIdentifier:isRTL]; TPBCommonInputTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBCommonInputTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } cell.inputDelegate = self; [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeCheck: { if ([model isKindOfClass:[TPBCheckTableCellModel class]]) { TPBCheckTableCellModel *cellModel = (TPBCheckTableCellModel *)model; BOOL isCustomizedCellHeight = cellModel.height.isCustomHeight; NSString *cellIdentifier = [TPBCheckTableCell cellIdentifier:isRTL]; TPBCheckTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBCheckTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel isCustomizedCellHeight:isCustomizedCellHeight]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeJumpSelect: { if ([model isKindOfClass:[TPBJumpSelectTableCellModel class]]) { TPBJumpSelectTableCellModel *cellModel = (TPBJumpSelectTableCellModel *)model; NSString *cellIdentifier = [TPBJumpSelectTableCell cellIdentifier:isRTL]; TPBJumpSelectTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBJumpSelectTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && TPBIsEmptyString(cellModel.title) && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeMenuSelect: { if ([model isKindOfClass:[TPBMenuSelectTableCellModel class]]) { TPBMenuSelectTableCellModel *cellModel = (TPBMenuSelectTableCellModel *)model; NSString *cellIdentifier = [TPBMenuSelectTableCell cellIdentifier:isRTL]; TPBMenuSelectTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBMenuSelectTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeListInput: { if ([model isKindOfClass:[TPBListInputTableCellModel class]]) { TPBListInputTableCellModel *cellModel = (TPBListInputTableCellModel *)model; NSString *cellIdentifier = [TPBListInputTableCell cellIdentifier:isRTL]; TPBListInputTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBListInputTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } cell.inputDelegate = self; [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; case TPBTableCellTypeTitleAction: { if ([model isKindOfClass:[TPBTitleActionTableCellModel class]]) { TPBTitleActionTableCellModel *cellModel = (TPBTitleActionTableCellModel *)model; NSString *cellIdentifier = [TPBTitleActionTableCell cellIdentifier:isRTL]; TPBTitleActionTableCell *cell; if (TPBA11yHelper.isVoiceOverOn) { cell = [[TPBTitleActionTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } if (cell == nil) { cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } [cell updateCellModel:cellModel]; [cell updateBottomSeparatorShow:!self.hideCellSeparator && !isLast && !cellModel.hideCellSeparator]; return cell; } } break; } return [[UITableViewCell alloc] init]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section < 0 || self.sectionArray.count <= indexPath.section) { return UITableViewAutomaticDimension; } TPBTableSectionModel *sectionModel = self.sectionArray[indexPath.section]; if (indexPath.row < 0 || sectionModel.cellModelArray.count <= indexPath.row) { return UITableViewAutomaticDimension; } TPBBaseTableCellModel *cellModel = sectionModel.cellModelArray[indexPath.row]; if (cellModel.height.isCustomHeight) { return cellModel.height.customHeight; } return UITableViewAutomaticDimension; } // Header - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return [UIView new]; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; if (sectionModel.customHeaderView != nil) { return sectionModel.customHeaderView; } if (TPBIsEmptyString(sectionModel.headerTitle) && sectionModel.headerAction == nil) { return [UIView new]; } TPBTableTextSectionHeader *headerView = [TPBTableTextSectionHeader new]; [headerView updateSectionModel:sectionModel]; return headerView; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return TPBDesign.list.sectionHeaderHeight; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; if (sectionModel.sectionHeaderHeight.isCustomHeight) { return sectionModel.sectionHeaderHeight.customHeight; } if (sectionModel.customHeaderView != nil) { return UITableViewAutomaticDimension; } if (TPBIsEmptyString(sectionModel.headerTitle) && sectionModel.headerAction == nil) { if (self.searchBarShow && section == 0) { return 10; } return TPBDesign.list.sectionHeaderHeight; } return UITableViewAutomaticDimension; } // Footer - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return [UIView new]; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; if (sectionModel.customFooterView != nil) { return sectionModel.customFooterView; } if (TPBIsEmptyString(sectionModel.footerTitle) && sectionModel.footerAction == nil) { return [UIView new]; } TPBTableTextSectionFooter *footerView = [TPBTableTextSectionFooter new]; [footerView updateSectionModel:sectionModel]; return footerView; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { if (section < 0 || self.sectionArray.count <= section) { return TPBDesign.list.sectionFooterHeight; } TPBTableSectionModel *sectionModel = self.sectionArray[section]; if (sectionModel.sectionFooterHeight.isCustomHeight) { return sectionModel.sectionFooterHeight.customHeight; } if (sectionModel.customFooterView != nil) { return UITableViewAutomaticDimension; } if (TPBIsEmptyString(sectionModel.footerTitle) && sectionModel.footerAction == nil) { return TPBDesign.list.sectionFooterHeight; } return UITableViewAutomaticDimension; } // TableViewCell点击 - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:NO]; if (indexPath.section < 0 || self.sectionArray.count <= indexPath.section) { return NO; } TPBTableSectionModel *sectionModel = self.sectionArray[indexPath.section]; if (indexPath.row < 0 || sectionModel.cellModelArray.count <= indexPath.row) { return NO; } TPBBaseTableCellModel *cellModel = sectionModel.cellModelArray[indexPath.row]; switch (cellModel.cellType) { case TPBTableCellTypeCustomCell: case TPBTableCellTypeCustomView: case TPBTableCellTypeTitleSubtitle: case TPBTableCellTypeSwitch: case TPBTableCellTypeCheck: case TPBTableCellTypeListButton: case TPBTableCellTypeJumpSelect: case TPBTableCellTypeMenuSelect: case TPBTableCellTypeProgress: case TPBTableCellTypeTitleAction: return YES; case TPBTableCellTypeCommonInput: case TPBTableCellTypeListInput: return NO; } } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:NO]; if (indexPath.section < 0 || self.sectionArray.count <= indexPath.section) { return; } TPBTableSectionModel *sectionModel = self.sectionArray[indexPath.section]; if (indexPath.row < 0 || sectionModel.cellModelArray.count <= indexPath.row) { return; } if (self.keyboardBehavior == TPBCommonTableKeyboardBehaviorDismissAndRespondClick) { [self tpbHideKeyboard]; } TPBBaseTableCellModel *model = sectionModel.cellModelArray[indexPath.row]; switch (model.cellType) { case TPBTableCellTypeCustomCell: { if ([model isKindOfClass:[TPBCustomTableCellBaseModel class]]) { TPBCustomTableCellBaseModel *cellModel = (TPBCustomTableCellBaseModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeCustomView: { if ([model isKindOfClass:[TPBCustomViewTableCellModel class]]) { TPBCustomViewTableCellModel *cellModel = (TPBCustomViewTableCellModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeTitleSubtitle: { if ([model isKindOfClass:[TPBTitleSubtitleTableCellModel class]]) { TPBTitleSubtitleTableCellModel *cellModel = (TPBTitleSubtitleTableCellModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeSwitch: { if ([model isKindOfClass:[TPBSwitchTableCellModel class]]) { TPBSwitchTableCellModel *cellModel = (TPBSwitchTableCellModel *)model; if (cellModel.switchDidClickHotZoneCallback) { cellModel.switchDidClickHotZoneCallback(); } } } break; case TPBTableCellTypeListButton: { if ([model isKindOfClass:[TPBListButtonTableCellModel class]]) { TPBListButtonTableCellModel *cellModel = (TPBListButtonTableCellModel *)model; if (cellModel.actionEnabled && cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeCheck: { if ([model isKindOfClass:[TPBCheckTableCellModel class]]) { TPBCheckTableCellModel *cellModel = (TPBCheckTableCellModel *)model; if (cellModel.checkEnabled && cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeJumpSelect: { if ([model isKindOfClass:[TPBJumpSelectTableCellModel class]]) { TPBJumpSelectTableCellModel *cellModel = (TPBJumpSelectTableCellModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } case TPBTableCellTypeTitleAction: { if ([model isKindOfClass:[TPBTitleActionTableCellModel class]]) { TPBTitleActionTableCellModel *cellModel = (TPBTitleActionTableCellModel *)model; if (cellModel.didSelectCellCallback) { cellModel.didSelectCellCallback(cellModel, indexPath); } } } break; case TPBTableCellTypeMenuSelect: break; case TPBTableCellTypeProgress: case TPBTableCellTypeCommonInput: case TPBTableCellTypeListInput: break; } } //- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{ // if (indexPath.row < 0 || indexPath.row >= self.cloudDeviceList.count) { // return NO; // } // TPBDMECDevice *ecDevice = self.cloudDeviceList[indexPath.row]; // return [self canForgetWithDevice:ecDevice]; //} //- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { // if (indexPath.row < 0 || indexPath.row >= self.cloudDeviceList.count) { // return @[]; // } // TPBDMECDevice *ecDevice = self.cloudDeviceList[indexPath.row]; // TPBWeakSelf; // UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:gControllerCloudAccess.controllerCloudAccessForget handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){ // TPBStrongSelf; // [_self popAlertControlForUnbindActionWithECDevice:ecDevice]; // }]; // deleteAction.backgroundColor = [UIColor tpbRed]; // return @[deleteAction]; //} #pragma mark - UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView { [self updateSearchBarPosition]; } #pragma mark - TPBTableSearchHeaderDelegate - (void)tpbTableSearchHeaderHideKeyboard { [self tpbHideKeyboard]; } #pragma mark - TPBTableCommonInputDelegate - (void)tableCommonInputFieldDidClickReturn:(TPBCommonInputView *)inputView textField:(UITextField *)textField { [self handleUserClickReturnForTextField:textField]; } #pragma mark - TPBTableListInputDelegate - (void)tableListInputFieldDidClickReturn:(TPBListInputTableCell *)inputCell textField:(UITextField *)textField { [self handleUserClickReturnForTextField:textField]; } #pragma mark - Private - (void)updateSearchBarPosition { CGFloat tableY = self.tableView.frame.origin.y; CGRect convertedRect = [self.tpbSearchBarPlaceholderView convertRect:self.tpbSearchBarPlaceholderView.bounds toView:self.view]; CGFloat diffY = convertedRect.origin.y - tableY; CGFloat targetConstant = MAX(0, diffY); if (self.searchBarTopConstraint.tpbConstant != targetConstant) { self.searchBarTopConstraint.tpbConstant = targetConstant; } } // 用户点击UITextField键盘Return - (void)handleUserClickReturnForTextField:(UITextField *)textField { if (textField.returnKeyType != UIReturnKeyNext) { [textField resignFirstResponder]; return; } if ([self.tableView focusNextTextField]) { } else { [textField resignFirstResponder]; } } - (void)updateTableHeader { if (self.searchBarShow) { CGFloat searchBarHeight = [self.tpbInnerSearchBar preferredHeight]; self.tpbSearchBarPlaceholderView.frame = CGRectMake(0, 0, self.view.bounds.size.width, searchBarHeight); self.tableView.tableHeaderView = self.tpbSearchBarPlaceholderView; self.searchBarHeightConstraint.tpbConstant = searchBarHeight; } else if (self.customTableHeaderView) { self.tableView.tableHeaderView = self.customTableHeaderView; } else { UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, CGFLOAT_MIN)]; self.tableView.tableHeaderView = view; } } #pragma mark - Property - (TPBEmptyView *)emptyView { if (!_emptyView) { _emptyView = [TPBEmptyView new]; _emptyView.hidden = YES; } return _emptyView; } - (UIView *)tpbSearchBarPlaceholderView { if (!_tpbSearchBarPlaceholderView) { _tpbSearchBarPlaceholderView = [UIView new]; } return _tpbSearchBarPlaceholderView; } - (TPBTableSearchHeader *)tpbInnerSearchBar { if (!_tpbInnerSearchBar) { CGRect frame = CGRectMake(0, 0, self.view.bounds.size.width, 62); _tpbInnerSearchBar = [[TPBTableSearchHeader alloc] initWithFrame:frame]; _tpbInnerSearchBar.delegate = self; _tpbInnerSearchBar.hidden = YES; _tpbInnerSearchBar.backgroundColor = [UIColor tpbBackground]; } return _tpbInnerSearchBar; } - (UITableView *)tableView { if (!_tableView) { _tableView = [[TPKeyboardAvoidingTableView alloc] initWithFrame:CGRectZero style:self.tableViewStyle]; if (@available(iOS 13.0, *)) { _tableView.automaticallyAdjustsScrollIndicatorInsets = YES; } if (@available(iOS 15.0, *)) { UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, CGFLOAT_MIN)]; _tableView.tableHeaderView = view; _tableView.sectionHeaderTopPadding = 0; } _tableView.backgroundColor = [UIColor clearColor]; _tableView.estimatedRowHeight = 72; _tableView.estimatedSectionHeaderHeight = 68; _tableView.showsHorizontalScrollIndicator = NO; _tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.sectionIndexColor = [UIColor tpbTableSectionIndexColor]; _tableView.delegate = self; _tableView.dataSource = self; NSArray<Class> *cellClassArray = @[ [TPBCustomViewTableCell class], [TPBTitleSubtitleTableCell class], [TPBSwitchTableCell class], [TPBProgressTableCell class], [TPBCommonInputTableCell class], [TPBCheckTableCell class], [TPBJumpSelectTableCell class], [TPBMenuSelectTableCell class], [TPBListInputTableCell class], [TPBListButtonTableCell class], [TPBTitleActionTableCell class] ]; for (Class cls in cellClassArray) { if ([cls isSubclassOfClass:[TPBBaseTableViewCell class]]) { NSString *cellIdentifier = [cls cellIdentifier]; [_tableView registerClass:cls forCellReuseIdentifier:cellIdentifier]; NSString *rtlCellIdentifier = [cls cellIdentifier:YES]; [_tableView registerClass:cls forCellReuseIdentifier:rtlCellIdentifier]; NSString *ltrCellIdentifier = [cls cellIdentifier:NO]; [_tableView registerClass:cls forCellReuseIdentifier:ltrCellIdentifier]; } } } return _tableView; } @end
11-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值