ios iOS7 分组 UITableView 圆角的解决方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19176179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:02:31  来源:igfitidea点击:

Workaround for rounded corners of grouped UITableView, iOS7

iosuitableviewios7

提问by OscarWyck

Since the introduction of iOS7, rounded corners for the cells of UITableView with grouped style is removed by Apple (confirmed here). Still, I am sure there are smart people out there who have built workarounds for this.

自从 iOS7 引入以来,Apple 删除了 UITableView 单元格的圆角,带有分组样式(在此处确认)。不过,我相信有一些聪明人为此建立了解决方法。

Please, to help me and a lot of other fellow iOS programmers, post your workarounds to get rounded corners for the cells in a UITableViewStyleGrouped in iOS7in this thread. It will be much appreciated!

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

采纳答案by Rigel Networks

Just add following UITableView delegate method in your code. It's really helped me to same issue like you for Table view in iOS7. Try following code taken from this answer by jvanmetre, may be it's also solved your problem:

只需在您的代码中添加以下 UITableView 委托方法。对于 iOS7 中的 Table 视图,它确实帮助我解决了与您相同的问题。尝试从 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;
        }
    }
}

回答by Roberto Ferraz

Considering you can have multiple groups in your table, some cells are rounding in just in the top corners, other just in the bottom, and others are not rounded. So I created here really fast a subclass (that can be really shortened) of UITableViewCell with the following methods:

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

A property that you can call anything you want, I called top and bottom:

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

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

The implementation:

实施:

- (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;
    }
}

In Swift 4.2:

在 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
  }
}

To use is simple, if your cell is the first of a group, set top = True, if it is the last cell, bottom = true, if the cell is the only on the group set both to true.

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

If you want more or less rounded, just change the radios from 10 to another value.

如果您想要或多或少四舍五入,只需将收音机从 10 更改为另一个值。

回答by Matt

Here is a slightly improved answer to that of Roberto Ferraz.

这是对 Roberto Ferraz 的稍微改进的答案。

It figures out the top and bottom cell for you (assuming there is no gap between the cells).

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

It also uses has trick from remove borders from groupthat works in iOS7

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

@interface CustomTableViewCell : UITableViewCell

Override messages:

覆盖消息:

#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];
    }
}

回答by born_stubborn

You can use UIImageView and set the corner radius like so:

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

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

To use this you should import quarts core:

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

#import <QuartzCore/QuartzCore.h>