10

自 iOS7 引入以来,具有分组样式的 UITableView 单元格的圆角已被 Apple 移除(在此处确认)。不过,我确信那里有聪明的人为此建立了解决方法。

为了帮助我和许多其他 iOS 程序员,请在此线程中发布您的解决方法,以便为 iOS7 中的 UITableViewStyleGrouped 中的单元格获得圆角。将不胜感激!

4

4 回答 4

18

考虑到您的表格中可以有多个组,一些单元格在顶角处四舍五入,其他单元格在底部,而其他单元格则不四舍五入。所以我在这里用以下方法非常快地创建了一个 UITableViewCell 的子类(可以真正缩短):

你可以调用任何你想要的属性,我称之为顶部和底部:

@property(nonatomic,assign) BOOL top,bottom;

实施:

- (void)layoutSubviews
{
    [super layoutSubviews];

    if(self.top && self.bottom)
    {
        self.layer.cornerRadius = 10;
        self.layer.masksToBounds = YES;
        return;
    }

    if (self.top)
    {
        CAShapeLayer *shape = [[CAShapeLayer alloc] init];
        shape.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:CGSizeMake(10, 10)].CGPath;
        self.layer.mask = shape;
        self.layer.masksToBounds = YES;
        return;
    }

    if (self.bottom)
    {
        CAShapeLayer *shape = [[CAShapeLayer alloc] init];
        shape.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height) byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(10, 10)].CGPath;
        self.layer.mask = shape;
        self.layer.masksToBounds = YES;
    }
}

在 Swift 4.2 中:

class MyCell: UITableViewCell {

var top = false
var bottom = false

override func layoutSubviews() {
    super.layoutSubviews()

    if top && bottom {
        layer.cornerRadius = 10
        layer.masksToBounds = true
        return
    }

    let shape = CAShapeLayer()
    let rect = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.size.height)
    let corners: UIRectCorner = self.top ? [.topLeft, .topRight] : [.bottomRight, .bottomLeft]

    shape.path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: 10, height: 10)).cgPath
    layer.mask = shape
    layer.masksToBounds = true
  }
}

使用很简单,如果您的单元格是组中的第一个,则设置为,top = True如果是最后一个单元格,bottom = true则设置为true

如果您想要或多或少的四舍五入,只需将无线电从 10 更改为另一个值。

于 2013-11-01T17:02:52.173 回答
4

只需在您的代码中添加以下 UITableView 委托方法。对于 iOS7 中的表格视图,它确实帮助我解决了与您一样的问题。尝试以下从 jvanmetre 的答案中获取的代码,它可能也解决了您的问题:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(tintColor)]) {
        if (tableView == tblProfileDetails) {    // self.tableview
            CGFloat cornerRadius = 5.f;
            cell.backgroundColor = UIColor.clearColor;
            CAShapeLayer *layer = [[CAShapeLayer alloc] init];
            CGMutablePathRef pathRef = CGPathCreateMutable();
            CGRect bounds = CGRectInset(cell.bounds, 5, 0);
            BOOL addLine = NO;
            if (indexPath.row == 0 && indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1) {
                CGPathAddRoundedRect(pathRef, nil, bounds, cornerRadius, cornerRadius);
            } 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));
                    addLine = YES;
            } 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));
            } else {
                CGPathAddRect(pathRef, nil, bounds);
                addLine = YES;
            }
            layer.path = pathRef;
            CFRelease(pathRef);
            layer.fillColor = [UIColor colorWithWhite:1.f alpha:0.8f].CGColor;

            if (addLine == YES) {
                CALayer *lineLayer = [[CALayer alloc] init];
                CGFloat lineHeight = (1.f / [UIScreen mainScreen].scale);
                lineLayer.frame = CGRectMake(CGRectGetMinX(bounds)+5, bounds.size.height-lineHeight, bounds.size.width-5, lineHeight);
                lineLayer.backgroundColor = tableView.separatorColor.CGColor;
                [layer addSublayer:lineLayer];
            }
            UIView *testView = [[UIView alloc] initWithFrame:bounds];
            [testView.layer insertSublayer:layer atIndex:0];
            testView.backgroundColor = UIColor.clearColor;
            cell.backgroundView = testView;
        }
    }
}
于 2013-11-12T10:12:58.927 回答
4

这是对 Roberto Ferraz 的回答略有改进。

它会为您计算出顶部和底部的单元格(假设单元格之间没有间隙)。

它还使用了从适用于 iOS7的组中删除边框的技巧

@interface CustomTableViewCell : UITableViewCell

覆盖消息:

#define radius 10

- (void)layoutSubviews {
    [super layoutSubviews];

    CGRect frame = self.frame;
    CGFloat top = frame.origin.y;
    CGFloat bottom = top + frame.size.height;
    UIRectCorner corners = UIRectCornerAllCorners;
    CAShapeLayer* mask = [CAShapeLayer layer];

    for (UIView* view in self.superview.subviews) {
        if (view.frame.origin.y + view.frame.size.height == top) {
            corners = corners & ~(UIRectCornerTopLeft|UIRectCornerTopRight);
        } else if (view.frame.origin.y == bottom) {
            corners = corners & ~(UIRectCornerBottomLeft|UIRectCornerBottomRight);
        }
    }

    mask.path = [UIBezierPath bezierPathWithRoundedRect:
                 CGRectMake(0, 0, frame.size.width, frame.size.height)
                                      byRoundingCorners:corners
                            cornerRadii:CGSizeMake(radius, radius)].CGPath;

    self.layer.mask = mask;
    self.layer.masksToBounds = YES;
}

/*
 iOS 7 workaround to get rid of top and bottom separators
*/
- (void) addSubview:(UIView*)view {
    if (view.frame.origin.x > 0 || view.frame.size.width < self.frame.size.width) {
        [super addSubview:view];
    }
}
于 2013-11-12T09:21:17.970 回答
-5

您可以使用 UIImageView 并像这样设置角半径:

CALayer * l = [self.cellBackgroundImage layer];
[l setMasksToBounds:YES];
[l setCornerRadius:5.0];

要使用它,您应该导入 quarts core:

#import <QuartzCore/QuartzCore.h>
于 2013-10-04T08:12:08.323 回答