您如何显示分组表部分的行分隔符?
Posted
技术标签:
【中文标题】您如何显示分组表部分的行分隔符?【英文标题】:How do you show line dividers for grouped table sections? 【发布时间】:2014-08-07 19:11:49 【问题描述】:我想模仿标准联系人应用程序的分组表(左)。每个部分的上方和下方都有灰线分隔线。在我的分组表(右)中,每个部分上方没有一行。更奇怪的是,中间部分根本没有线条。
#import "GroupViewController.h"
#import "UserCollectionViewCell.h"
#import "UIView+position.h"
#import "UIColor+style.h"
#import "UserPublicViewController.h"
#import "RecipientsGroupsModel.h"
static NSString* AVATAR_CELL_ID = @"groupUserCollectionUserView";
static const CGFloat AVATAR_ITEM_SPACING = 16.0;
static const CGFloat AVATAR_LINE_SPACING = 9.0;
static const CGFloat AVATAR_MARGIN = 15.5;
static const CGFloat AVATAR_CELL_WIDTH = 45.0;
static const CGFloat AVATAR_CELL_HEIGHT = 58.0;
typedef enum
GroupViewControllerTableSectionTitle,
GroupViewControllerTableSectionUsers,
GroupViewControllerTableSectionDelete
GroupViewControllerTableSection;
@interface GroupViewController ()
@property(nonatomic, strong) Group* group;
@property(nonatomic, strong) UICollectionView* avatarCollectionView;
@property(nonatomic, readonly) CGFloat usersHeight;
- (void)didLongTapAvatars:(UILongPressGestureRecognizer*)gesture;
@end
@implementation GroupViewController
#pragma mark UIViewController
- (NSString*)title
return @"Group";
- (void)loadView
[super loadView];
self.view.backgroundColor = [UIColor backgroundColor];
- (void)viewDidLoad
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
[super setEditing:editing animated:animated];
[self.tableView reloadData];
[self.avatarCollectionView reloadData];
#pragma mark GroupViewController ()
- (void)didLongTapAvatars:(UILongPressGestureRecognizer *)gesture
if (gesture.state == UIGestureRecognizerStateBegan)
[self setEditing:!self.isEditing animated:YES];
- (CGFloat)usersHeight
return ceilf(
self.group.users.count
/ floorf(
(
self.view.width
- 2 * AVATAR_MARGIN
+ AVATAR_ITEM_SPACING
)
/ (
AVATAR_ITEM_SPACING
+ AVATAR_CELL_WIDTH
)
)
)
* (AVATAR_CELL_HEIGHT + AVATAR_LINE_SPACING)
+ AVATAR_LINE_SPACING;
#pragma mark GroupViewController
- (instancetype)initWithGroup:(Group *)group
if (self = [super init])
self.group = group;
return self;
#pragma mark UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
switch (indexPath.section)
case GroupViewControllerTableSectionTitle:
case GroupViewControllerTableSectionDelete:
return 44.0f;
break;
case GroupViewControllerTableSectionUsers:
return self.usersHeight;
break;
default:
return 0.0f;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
return 22.0f;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
switch (section)
case GroupViewControllerTableSectionDelete:
return 22.0f;
break;
default:
return 0.0f;
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
// ios 7 applies a transclucent view if you don't return your own view
return [[UIView alloc] init];
- (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
return [[UIView alloc] init];
#pragma mark UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
if (self.isEditing)
return GroupViewControllerTableSectionDelete + 1;
else
return GroupViewControllerTableSectionUsers + 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return 1;
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
NSString* identifier = [NSNumber numberWithInteger:indexPath.section].stringValue;
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
switch (indexPath.section)
case GroupViewControllerTableSectionTitle:
cell.textLabel.text = self.group.title;
break;
case GroupViewControllerTableSectionUsers:
if (self.avatarCollectionView == nil)
UICollectionViewFlowLayout* layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
layout.sectionInset = UIEdgeInsetsMake(
AVATAR_LINE_SPACING,
AVATAR_MARGIN,
AVATAR_LINE_SPACING,
AVATAR_MARGIN
);
layout.itemSize = CGSizeMake(AVATAR_CELL_WIDTH, AVATAR_CELL_HEIGHT);
layout.minimumInteritemSpacing = AVATAR_ITEM_SPACING;
layout.minimumLineSpacing = AVATAR_LINE_SPACING;
self.avatarCollectionView = [[UICollectionView alloc]
initWithFrame:CGRectMake(
0.0,
0.0,
self.view.width,
self.usersHeight
)
collectionViewLayout:layout
];
self.avatarCollectionView.backgroundColor = [UIColor clearColor];
self.avatarCollectionView.dataSource = self;
self.avatarCollectionView.delegate = self;
[self.avatarCollectionView registerClass:[UserCollectionViewCell class] forCellWithReuseIdentifier:AVATAR_CELL_ID];
[self.avatarCollectionView addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongTapAvatars:)]];
[cell.contentView addSubview:self.avatarCollectionView];
break;
case GroupViewControllerTableSectionDelete:
cell.textLabel.text = @"Delete Group";
cell.textLabel.textColor = [UIColor redColor];
break;
return cell;
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
return NO;
#pragma mark UICollectionViewDataSource
- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
UserCollectionViewCell* cell;
cell = [self.avatarCollectionView dequeueReusableCellWithReuseIdentifier:AVATAR_CELL_ID forIndexPath:indexPath];
cell.user = [self.group.users objectAtIndex:indexPath.row];
cell.isEditing = self.isEditing;
return cell;
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
return self.group.users.count;
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
return 1;
#pragma mark UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
User* user = [self.group.users objectAtIndex:indexPath.row];
if (self.isEditing)
if (self.group.users.count <= 1)
[RecipientsGroupsModel removeGroup:self.group];
[self.navigationController popViewControllerAnimated:YES];
else
[self.group.users removeObject:user];
[RecipientsGroupsModel updateGroup:self.group];
[self.avatarCollectionView deleteItemsAtIndexPaths:@[indexPath]];
else
[self.navigationController pushViewController:[[UserPublicViewController alloc] initWithUser:user] animated:YES];
@end
【问题讨论】:
【参考方案1】:您可以使用 UITableViewDelegate 方法:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
您可以在其中为任何部分的页眉和页脚指定所需的任何高度。如果您不需要页眉或页脚,则返回 0。
然后使用其他两种方法:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
在它们中,您可以编写自定义代码以使它们看起来像您想要的那样:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
view.backgroundColor = [UIColor grayColor];
// ...
// Other customizations, like adding the gray line, etc.
// ...
return view;
【讨论】:
以上是关于您如何显示分组表部分的行分隔符?的主要内容,如果未能解决你的问题,请参考以下文章
RecyclerView的行项目视图隐藏/显示在Recyclerview的滚动上搞砸了