我有一个带有UITableView的xib文件,我想使用委托方法tableView:viewForHeaderInSection:添加一个自定义的部分标题视图.有没有可能在Interface Builder中设计它,然后以编程方式更改其中的一些子视图的属性?
我的UITableView具有更多的部分标题,因此在Interface Builder中创建一个UIView并返回它不起作用,因为我必须复制它,但没有任何好的方法.归档和取消归档它对于UIImages不起作用,所以UIImageViews将显示空白.
此外,我不想以编程方式创建它们,因为它们太复杂,并且生成的代码将难以阅读和维护.
编辑1:对于那些还不明白的人,真的需要一些无用的代码来理解它,这里是我的tableView:viewForHeaderInSection:方法:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) { return nil; } CGSize headerSize = CGSizeMake(self.view.frame.size.width,100); /* wrapper */ UIView *wrapperView = [UIView viewWithSize:headerSize]; wrapperView.backgroundColor = [UIColor colorWithHexString:@"2670ce"]; /* title */ CGPoint titleMargin = CGPointMake(15,8); UILabel *titleLabel = [UILabel labelWithText:self.categoriesNames[section] andFrame:CGEasyRectMake(titleMargin,CGSizeMake(headerSize.width - titleMargin.x * 2,20))]; titleLabel.textColor = [UIColor whiteColor]; titleLabel.font = [UIFont fontWithStyle:FontStyleRegular andSize:14]; [wrapperView addSubview:titleLabel]; /* body wrapper */ CGPoint bodyWrapperMargin = CGPointMake(10,8); CGPoint bodyWrapperViewOrigin = CGPointMake(bodyWrapperMargin.x,CGRectGetMaxY(titleLabel.frame) + bodyWrapperMargin.y); CGSize bodyWrapperViewSize = CGSizeMake(headerSize.width - bodyWrapperMargin.x * 2,headerSize.height - bodyWrapperViewOrigin.y - bodyWrapperMargin.y); UIView *bodyWrapperView = [UIView viewWithFrame:CGEasyRectMake(bodyWrapperViewOrigin,bodyWrapperViewSize)]; [wrapperView addSubview:bodyWrapperView]; /* image */ NSInteger imageSize = 56; NSString *imageName = [self getCategoryResourceItem:section + 1][@"image"]; UIImageView *imageView = [UIImageView imageViewWithImage:[UIImage imageNamed:imageName] andFrame:CGEasyRectMake(CGPointZero,CGEqualSizeMake(imageSize))]; imageView.layer.masksToBounds = YES; imageView.layer.cornerRadius = imageSize / 2; [bodyWrapperView addSubview:imageView]; /* labels */ NSInteger labelsWidth = 60; UILabel *firstLabel = [UILabel labelWithText:@"first" andFrame:CGRectMake(imageSize + bodyWrapperMargin.x,labelsWidth,16)]; [bodyWrapperView addSubview:firstLabel]; UILabel *secondLabel = [UILabel labelWithText:@"second" andFrame:CGRectMake(imageSize + bodyWrapperMargin.x,20,16)]; [bodyWrapperView addSubview:secondLabel]; UILabel *thirdLabel = [UILabel labelWithText:@"third" andFrame:CGRectMake(imageSize + bodyWrapperMargin.x,40,16)]; [bodyWrapperView addSubview:thirdLabel]; [@[ firstLabel,secondLabel,thirdLabel ] forEachView:^(UIView *view) { UILabel *label = (UILabel *)view; label.textColor = [UIColor whiteColor]; label.font = [UIFont fontWithStyle:FontStyleLight andSize:11]; }]; /* line */ UIView *lineView = [UIView viewWithFrame:CGRectMake(imageSize + labelsWidth + bodyWrapperMargin.x * 2,bodyWrapperMargin.y,1,bodyWrapperView.frame.size.height - bodyWrapperMargin.y * 2)]; lineView.backgroundColor = [UIColor whiteColorWithAlpha:0.2]; [bodyWrapperView addSubview:lineView]; /* progress */ CGPoint progressSliderOrigin = CGPointMake(imageSize + labelsWidth + bodyWrapperMargin.x * 3 + 1,bodyWrapperView.frame.size.height / 2 - 15); CGSize progressSliderSize = CGSizeMake(bodyWrapperViewSize.width - bodyWrapperMargin.x - progressSliderOrigin.x,30); UiSlider *progressSlider = [UiSlider viewWithFrame:CGEasyRectMake(progressSliderOrigin,progressSliderSize)]; progressSlider.value = [self getCategoryProgress]; [bodyWrapperView addSubview:progressSlider]; return wrapperView; }
我希望它看起来像这样:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) { return nil; } SectionView *sectionView = ... // get the view that is already designed in the Interface Builder sectionView.headerText = self.categoriesNames[section]; sectionView.headerImage = [self getCategoryResourceItem:section + 1][@"image"]; sectionView.firstLabelText = @"first"; sectionView.secondLabelText = @"second"; sectionView.thirdLabelText = @"third"; sectionView.progress = [self getCategoryProgress]; return wrapperView; }
编辑2:我不使用故事板,只是.xib文件.此外,我没有一个UITableViewController,只是一个UIViewController,其中我添加了一个UITableView.
解决方法
故事板或XIB
>相同的故事板:
return tableView.dequeueReusableCell(withIdentifier: "header")
>分离XIB(附加步骤:您必须先注册该Nib):
tableView.register(UINib(nibName: "XIBSectionHeader",bundle:nil),forCellReuseIdentifier: "xibheader")
要从故事板而不是XIB加载,请参阅this Stack Overflow answer.
使用UITableViewCell在IB中创建节标题
利用一个section头是一个普通的UIView,UITableViewCell也是一个UIView的事实.在Interface Builder中,拖动&将表视图单元格从对象库中删除到表视图原型内容.
向新添加的表视图单元添加标识符,并根据需要自定义其外观.对于这个例子,我使用了标题.
使用dequeueReusableCell:withIdentifier来定位您的段标题,就像任何表视图单元格一样.您将需要提供heightForHeaderInSection,为了清楚,硬编码为44
//MARK: UITableViewDelegate override func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? { // This is where you would change section header content return tableView.dequeueReusableCell(withIdentifier: "header") } override func tableView(_ tableView: UITableView,heightForHeaderInSection section: Int) -> CGFloat { return 44 }
Swift 2&早期:
return tableView.dequeueReusableCellWithIdentifier("header") as? UIView self.tableView.registerNib(UINib(nibName: "XIBSectionHeader",forCellReuseIdentifier: "xibheader")
►在GitHub上查找此解决方案,并在Swift Recipes上查看更多详细信息.