tableView圆角封装
程序员文章站
2024-03-23 08:58:16
...
很多界面会使用tableView,系统也提供了UITableViewController,基于它做一下简答的封装,实现tableView的圆角设置。
封装
- MMTableViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface MMTableViewController : UITableViewController
// Set the rounded corners for section, if > 0 the section corner is round.
@property (nonatomic, assign) CGFloat sectionCornerRadius;
@end
NS_ASSUME_NONNULL_END
这里通过属性sectionCornerRadius来设置tableView的圆角。
- MMTableViewController.m
#import "MMTableViewController.h"
@interface MMTableViewController ()
@end
@implementation MMTableViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// 默认是YES,在viewWillAppear:的时候会清空当前的cell,这里禁止此操作。
self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)setSectionCornerRadius:(CGFloat)sectionCornerRadius
{
_sectionCornerRadius = sectionCornerRadius;
// 去除tableView自带的线条,否则会和我们绘制的线条重合
if (_sectionCornerRadius > 0) {
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 0;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// 当 sectionCornerRadius > 0 时,设置圆角
if (self.sectionCornerRadius > 0)
{
// 设置cell的背景色透明,否则边角上会显示出来。
cell.backgroundColor = UIColor.clearColor;
// 圆角大小
CGFloat cornerRadius = self.sectionCornerRadius;
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
CAShapeLayer *borderLayer = [[CAShapeLayer alloc] init];
CAShapeLayer *backgroundLayer = [[CAShapeLayer alloc] init];
CGMutablePathRef pathRef = CGPathCreateMutable();
CGMutablePathRef borderPathRef = CGPathCreateMutable();
CGRect bounds = CGRectInset(cell.bounds, 0, 0);
// 是否需要画线,默认为NO
BOOL addLine = NO;
// 绘制每个section的第一个和最后一个row
if (indexPath.row == 0 && indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1)
{
CGPathAddRoundedRect(pathRef, nil, bounds, cornerRadius, cornerRadius);
CGPathAddRoundedRect(borderPathRef, nil, bounds, cornerRadius, cornerRadius);
}
// 绘制每个section的第一个cell
else if (indexPath.row == 0)
{
CGPathMoveToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
CGPathAddArcToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds), CGRectGetMidX(bounds), CGRectGetMinY(bounds), cornerRadius);
CGPathAddArcToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds));
CGPathMoveToPoint(borderPathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
CGPathAddArcToPoint(borderPathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds), CGRectGetMidX(bounds), CGRectGetMinY(bounds), cornerRadius);
CGPathAddArcToPoint(borderPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
CGPathAddLineToPoint(borderPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds));
addLine = YES;
}
// 绘制每个section的最后个cell
else if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1)
{
CGPathMoveToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGPathAddArcToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds), CGRectGetMidX(bounds), CGRectGetMaxY(bounds), cornerRadius);
CGPathAddArcToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));
CGPathMoveToPoint(borderPathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGPathAddArcToPoint(borderPathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds), CGRectGetMidX(bounds), CGRectGetMaxY(bounds), cornerRadius);
CGPathAddArcToPoint(borderPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
CGPathAddLineToPoint(borderPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));
}
// 绘制每个section中间的cell
else
{
CGPathAddRect(pathRef, nil, bounds);
CGPathMoveToPoint(borderPathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGPathAddLineToPoint(borderPathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
CGPathMoveToPoint(borderPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));
CGPathAddLineToPoint(borderPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds));
addLine = YES;
}
layer.path = pathRef;
backgroundLayer.path = pathRef;
CFRelease(pathRef);
layer.fillColor = [UIColor colorWithWhite:1.f alpha:0.8f].CGColor; //填充颜色
borderLayer.path = borderPathRef;
CFRelease(borderPathRef);
borderLayer.fillColor = [UIColor clearColor].CGColor; //
borderLayer.lineWidth = 1/[[UIScreen mainScreen] scale];
borderLayer.strokeColor = tableView.separatorColor.CGColor; //绘制边缘
if (addLine == YES) {
CALayer *lineLayer = [[CALayer alloc] init];
CGFloat lineHeight = (1.f / [UIScreen mainScreen].scale);
lineLayer.frame = CGRectMake(CGRectGetMinX(bounds)+10, bounds.size.height-lineHeight, bounds.size.width-20, lineHeight);
lineLayer.backgroundColor = tableView.separatorColor.CGColor; //绘制中间间隔线
[layer addSublayer:lineLayer];
}
UIView *testView = [[UIView alloc] initWithFrame:bounds];
[testView.layer insertSublayer:layer atIndex:0];
[testView.layer insertSublayer:borderLayer above:layer];
testView.backgroundColor = UIColor.clearColor;
cell.backgroundView = testView;
//以上方法存在缺陷当点击cell时还是出现cell方形效果,因此还需要添加以下方法
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:bounds];
backgroundLayer.fillColor = tableView.separatorColor.CGColor;
[selectedBackgroundView.layer insertSublayer:backgroundLayer atIndex:0];
selectedBackgroundView.backgroundColor = UIColor.clearColor;
cell.selectedBackgroundView = selectedBackgroundView;
}
}
@end
以上方法是借鉴了网上别人的实现方式,都大差不离。
cell向内缩进
一般的我们设置tableView圆角,会设置cell向内缩进,在自定义的cell里面添加如下设置:
// 设置cell向内缩进
- (void)setFrame:(CGRect)frame
{
NSInteger insert = 45;
frame.origin.x += insert;
frame.size.width -= 2 * insert;
[super setFrame:frame];
}
效果
圆角+缩进
直角+缩进:
默认