Objective-C中如何给UITableView底部附加Xib实现类Footer滚动效果
嘿,这个需求我之前做项目的时候刚好实现过,最贴合系统footer滚动效果的方案是直接用UITableView自带的tableFooterView,另外也可以把自定义nib做成最后一个section的cell,两种方式都给你详细讲讲Objective-C的实现步骤:
这种方式是系统原生支持的,footer会跟着表格内容无缝滚动,当内容不足一屏时会固定在屏幕底部,完全符合你的需求:
创建自定义Footer类和对应的Xib
新建一个继承自UIView的类(比如命名为CustomTableFooter),同时创建同名的Xib文件。在Xib里拖拽按钮、文本框等你需要的控件,设置好AutoLayout约束,把控件关联到CustomTableFooter的属性上(比如submitButton、inputTextField)。加载Xib并设置为tableFooterView
在你的ViewController里,添加加载Xib的方法,然后在viewDidLoad中设置给tableView:// 加载自定义Footer的Xib - (CustomTableFooter *)loadCustomFooter { NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:@"CustomTableFooter" owner:self options:nil]; return nibViews.firstObject; } - (void)viewDidLoad { [super viewDidLoad]; // 初始化tableView(如果是Storyboard拖拽的可以跳过这部分) self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; self.tableView.delegate = self; self.tableView.dataSource = self; [self.view addSubview:self.tableView]; // 设置自定义Footer CustomTableFooter *footerView = [self loadCustomFooter]; // 手动设置高度,或者后续通过AutoLayout自动计算 footerView.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 120); self.tableView.tableFooterView = footerView; // 给Footer里的按钮绑定点击事件 [footerView.submitButton addTarget:self action:@selector(footerButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; } // 按钮点击事件处理 - (void)footerButtonTapped:(UIButton *)sender { NSString *inputText = ((CustomTableFooter *)self.tableView.tableFooterView).inputTextField.text; NSLog(@"用户输入:%@", inputText); // 这里写你的业务逻辑 }实现Footer高度自适应(可选)
如果你的Footer内容高度不固定,可以在viewDidLayoutSubviews里自动计算高度:- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; CustomTableFooter *footerView = (CustomTableFooter *)self.tableView.tableFooterView; [footerView setNeedsLayout]; [footerView layoutIfNeeded]; // 计算自适应高度 CGFloat adaptiveHeight = [footerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; CGRect footerFrame = footerView.frame; footerFrame.size.height = adaptiveHeight; footerView.frame = footerFrame; self.tableView.tableFooterView = footerView; }
如果你的Footer需要和表格Cell有交互联动,也可以把它做成最后一个Section的Cell,滚动效果和Footer几乎一致:
创建自定义FooterCell类和Xib
新建继承自UITableViewCell的类(比如CustomFooterCell),并创建同名Xib,在Xib里添加按钮、文本框并关联属性。修改TableView的数据源方法
在数据源中增加一个Section,把FooterCell放在最后一个Section里:// 假设原有内容是1个Section,Footer是第2个Section - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section == 0) { return self.dataArray.count; // 原有内容的行数 } else { return 1; // FooterCell的行数 } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 0) { // 原有内容Cell的创建逻辑 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ContentCell"]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ContentCell"]; } cell.textLabel.text = self.dataArray[indexPath.row]; return cell; } else { // FooterCell的创建 CustomFooterCell *footerCell = [tableView dequeueReusableCellWithIdentifier:@"FooterCell"]; if (!footerCell) { NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:@"CustomFooterCell" owner:self options:nil]; footerCell = nibViews.firstObject; } [footerCell.submitButton addTarget:self action:@selector(footerCellButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; return footerCell; } } // 设置FooterCell的高度 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 1) { return 120; // 或者用UITableViewAutomaticDimension实现自适应 } return UITableViewAutomaticDimension; } // FooterCell按钮点击事件 - (void)footerCellButtonTapped:(UIButton *)sender { // 获取输入框内容 UITableViewCell *cell = (UITableViewCell *)sender.superview.superview; NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; CustomFooterCell *footerCell = (CustomFooterCell *)[self.tableView cellForRowAtIndexPath:indexPath]; NSLog(@"用户输入:%@", footerCell.inputTextField.text); }
- 使用
tableFooterView时,它会在表格内容不足一屏时固定在屏幕底部,内容超过一屏时会跟着滚动,完全和系统默认Footer的行为一致,这是最推荐的方案。 - 不管用哪种方式,Xib里的控件都要正确关联到自定义类的属性,避免出现空指针问题。
- 如果需要自适应高度,一定要确保Xib里的AutoLayout约束是完整的,没有冲突,这样才能正确计算高度。
内容的提问来源于stack exchange,提问作者kaddie

