【iOS】UITableViewCell實現分割槽圓角
阿新 • • 發佈:2021-06-30
可以在tableView的willDisplayCell回撥中實現,常用的實現方式有兩種
-
根據cell在section中的位置,利用UIBezierPath繪製蒙層,從而實現分割槽圓角
cell可分為4種:
1. 當前section有且僅有1行,此時該行cell既是第一行的cell,也是最後一行的cell,四個角都要繪製圓角
2. 每個section中第一行的cell,且當前section不止1行,此時cell的左上角和右上角需要繪製圓角
3. 每個section中最後一行的cell,且當前section不止1行,此時cell的左下角和右下角需要繪製圓角
4. 當前cell既不是所在section的第一行,也不是最後一行,則cell的四個角都不需要繪製圓角
實現程式碼參考:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { // Cell 分割槽圓角 CGFloat radius = 10; if ([tableView numberOfRowsInSection:indexPath.section] == 1) { // 當前section有且僅有1行,則四個角都要繪製圓角 UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:radius]; CAShapeLayer*maskLayer = [[CAShapeLayer alloc] init]; maskLayer.frame = cell.bounds; maskLayer.path = maskPath.CGPath; cell.layer.mask = maskLayer; } else { // 當前section不止1行 if (indexPath.row == 0) { // 當前cell為第一行 UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:UIRectCornerTopLeft| UIRectCornerTopRight cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; maskLayer.frame = cell.bounds; maskLayer.path = maskPath.CGPath; cell.layer.mask = maskLayer; } else if (indexPath.row == [tableView numberOfRowsInSection] - 1) { // 當前cell為最後一行 UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; maskLayer.frame = cell.bounds; maskLayer.path = maskPath.CGPath; cell.layer.mask = maskLayer; } else { // 當前cell為中間行 cell.layer.mask = nil; } } }
注意當cell為中間行時需要將cell.layer.mask置為nil,否則由於cell的重用機制,會出現section中間行的cell也被繪製圓角的異常情況。
-
用UIBezierPath繪製蒙層,之後通過設定UITableViewCell的backgroundView和selectedBackgroundView實現分割槽圓角
cell的分類方式與第一種方法相同
實現程式碼參考:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { // Cell 分割槽圓角 cell.backgroundColor = [UIColor clearColor]; CGFloat radius = 10; CAShapeLayer *normalLayer = [[CAShapeLayer alloc] init]; CAShapeLayer *selectLayer = [[CAShapeLayer alloc] init]; NSInteger rowNumber = [tableView numberOfRowsInSection:indexPath.section]; UIBezierPath *bezierPath = nil; if (rowNumber == 1) { bezierPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)]; } else { if (indexPath.row == 0) { bezierPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(radius, radius)]; } else if (indexPath.row == rowNumber - 1) { bezierPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(radius, radius)]; } else { bezierPath = [UIBezierPath bezierPathWithRect:cell.bounds]; } } normalLayer.path = bezierPath.CGPath; selectLayer.path = bezierPath.CGPath; UIView *normalBgView = [[UIView alloc] initWithFrame:cell.bounds]; normalLayer.fillColor = [[UIColor whiteColor] CGColor]; [normalBgView.layer insertSublayer:normalLayer atIndex:0]; normalBgView.backgroundColor = [UIColor clearColor]; cell.backgroundView = normalBgView; UIView *selectBgView = [[UIView alloc] initWithFrame:cell.bounds]; selectLayer.fillColor = [[UIColor blackColor] CGColor]; [selectBgView.layer insertSublayer:selectLayer atIndex:0]; selectBgView.backgroundColor = [UIColor clearColor]; cell.selectedBackgroundView = selectBgView;
這種方法的好處在於可以設定cell的fillColor,即選中時的顏色,記得要用UIColor.CGColor,否則顏色無法展示。但是這種實現比第一種方法更加重量級,如果只需要給UITableViewCell繪製分割槽圓角,推薦第一種方式。