Objective c 仅在UIView顶部的圆角

Objective c 仅在UIView顶部的圆角,objective-c,uiview,core-graphics,rounded-corners,Objective C,Uiview,Core Graphics,Rounded Corners,您好,我正在搜索一个干净的解决方案,而不覆盖drawRect或类似的内容,以创建UIView,在视图顶部有圆角。我这里的主要问题是,如果视图正在调整大小或类似的事情,则创建变量解决方案。 有干净的解决办法吗苹果在第一个表格项目上也是如此。要做到这一点并不难。最简单的方法是以您想要的形状定义一条路径,并用您想要用作背景的任何颜色填充它。您可以为此使用UIBezierPath或CGPath。例如,使用CGPath,可以使用CGMoveToPoint()、CGAddLineToPoint()和CGAd

您好,我正在搜索一个干净的解决方案,而不覆盖
drawRect
或类似的内容,以创建
UIView
,在视图顶部有圆角。我这里的主要问题是,如果视图正在调整大小或类似的事情,则创建变量解决方案。
有干净的解决办法吗苹果在第一个表格项目上也是如此。要做到这一点并不难。

最简单的方法是以您想要的形状定义一条路径,并用您想要用作背景的任何颜色填充它。您可以为此使用
UIBezierPath
CGPath
。例如,使用
CGPath
,可以使用
CGMoveToPoint()
CGAddLineToPoint()
CGAddArc()
等方法构造路径。然后用
CGContextFillPath()
填充它。请查看以进行完整的讨论

另一种方法是添加具有圆角的子视图(可以设置子视图的图层的cornerRadius特性),但让父视图剪裁子视图的一侧

第三种方法是添加具有所需形状的背景图像。您可以使角点透明,并使视图的背景透明,从而获得所需的效果。不过,这在调整大小时效果不太好


您在哪里卡住了?

您可以通过在视图的图层上设置一个
遮罩来完成此操作:

CAShapeLayer * maskLayer = [CAShapeLayer layer];
maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: self.bounds byRoundingCorners: UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii: (CGSize){10.0, 10.}].CGPath;

self.layer.mask = maskLayer;
重要提示:您应该在视图的
layoutSubviews()
方法中执行此操作,因此已从情节提要调整视图的大小



在斯威夫特中,我在艾希礼的帮助下解决了这个问题

首先,我将UIView子类化。为我的类创建自己的构造函数,名为
-(id)initWithContentView:(UIView*)aView forTableView:(UITableView*)table和index:(nsindepath*)indepath。在这个构造器中,我决定要设置什么样的表单元格样式

然后我覆盖l
-(void)layoutSubviews
,创建
现金流图层
,并应用图层掩码

.h文件代码

typedef enum {
    tableCellMiddle,
    tableCellTop,
    tableCellBottom,
    tableCellSingle
} tableCellPositionValue;

@interface TableCellBackgrounds : UIView
{
    tableCellPositionValue position;
}

- (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath;

@end
- (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath
{
    self = [super initWithFrame:aView.frame];

    [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth];

    if(self)
    {
        [self setBackgroundColor:[UIColor colorWithRed:(float)230/255 green:(float)80/255 blue:(float)70/255 alpha:1]];

        if(table.style == UITableViewStyleGrouped)
        {
            int rows = [table numberOfRowsInSection:indexPath.section];


            if(indexPath.row == 0 && rows == 1)
            {
                self.layer.cornerRadius = 11;
                position = tableCellSingle;
            }
            else if (indexPath.row == 0)
                position = tableCellTop;
            else if (indexPath.row != rows - 1) 
                position = tableCellMiddle;
            else 
                position = tableCellBottom;
        }
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    if(position == tableCellTop)
    {
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:(CGSize){10.0, 10.0}].CGPath;
        self.layer.mask = maskLayer;
    }
    else if (position == tableCellBottom)
    {
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:(CGSize){10.0, 10.0}].CGPath;
        self.layer.mask = maskLayer;
    } 
}
.m文件代码

typedef enum {
    tableCellMiddle,
    tableCellTop,
    tableCellBottom,
    tableCellSingle
} tableCellPositionValue;

@interface TableCellBackgrounds : UIView
{
    tableCellPositionValue position;
}

- (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath;

@end
- (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath
{
    self = [super initWithFrame:aView.frame];

    [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth];

    if(self)
    {
        [self setBackgroundColor:[UIColor colorWithRed:(float)230/255 green:(float)80/255 blue:(float)70/255 alpha:1]];

        if(table.style == UITableViewStyleGrouped)
        {
            int rows = [table numberOfRowsInSection:indexPath.section];


            if(indexPath.row == 0 && rows == 1)
            {
                self.layer.cornerRadius = 11;
                position = tableCellSingle;
            }
            else if (indexPath.row == 0)
                position = tableCellTop;
            else if (indexPath.row != rows - 1) 
                position = tableCellMiddle;
            else 
                position = tableCellBottom;
        }
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    if(position == tableCellTop)
    {
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:(CGSize){10.0, 10.0}].CGPath;
        self.layer.mask = maskLayer;
    }
    else if (position == tableCellBottom)
    {
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:(CGSize){10.0, 10.0}].CGPath;
        self.layer.mask = maskLayer;
    } 
}

刚刚试用了
Swift 3.0
Xcode 8.0

记住
viewDidLayoutSubviews()
layoutSubViews
中将按钮设置为 @罗布描述道

当您想更改按钮背景时,只需拨打:

yourButton.backgroundColor = UIColor.someColour
资料来源:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    yourButton.layer.masksToBounds = true
    yourButton.roundCorners(corners: [.topLeft,.topRight], radius: 5)
}

extension UIButton
{
    func roundCorners(corners:UIRectCorner, radius: CGFloat)
    {
        let maskLayer = CAShapeLayer()
        maskLayer.path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)).cgPath
        self.layer.mask = maskLayer
    }
}
  • 结果如下:
默认状态:

所选国家:


希望这有帮助

使用swift 3.0,下面的内容对我很有用

let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 10, height: 10)).cgPath
(imageView.)layer.mask = maskLayer
重要提示:确保这是在“布局子视图”中,而不是在“awakeFromNib”(如果您使用的是TableViewCell)或UIView的类似视图中,或者只有左上角是圆形的

 CAShapeLayer * maskLayer = [CAShapeLayer layer];
    maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: registerbtn.bounds byRoundingCorners: UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii: (CGSize){9.0, 12.0}].CGPath;

    registerbtn.layer.mask = maskLayer;

这将只执行一个圆角

UIView的扩展,该扩展将圆角选定的角(Swift 4):

例如:

ratingView.roundCorners([.topLeft, .topRight, .bottomRight], radius: 6)

对于iOS11及更高版本,可以使用视图的图层特性:

@property CACornerMask maskedCorners

定义在使用拐角半径属性时四个拐角中的哪一个接收遮罩。默认为所有四个角。(苹果文档)

现代简易解决方案

iOS 11+

现在,我们在视图的图层上有了
maskedCorners
属性&它使生活变得更加轻松

只需设置所需的角半径并指定应遮罩的角。最好的部分是,这可以很好地处理边界-层边界将跟随层的边缘,无论它是圆形的还是不圆形的!在操场上尝试以下代码(记住按
command+option+return打开实时视图,以便查看它的外观)

下面是它的样子:

[oCollectionViewCell.layer setMasksToBounds:YES];
[oCollectionViewCell.layer setCornerRadius:5.0];
[oCollectionViewCell.layer setMaskedCorners:kCALayerMinXMinYCorner|kCALayerMaxXMinYCorner];

在Objective-C中,它看起来像:

[oCollectionViewCell.layer setMasksToBounds:YES];
[oCollectionViewCell.layer setCornerRadius:5.0];
[oCollectionViewCell.layer setMaskedCorners:kCALayerMinXMinYCorner|kCALayerMaxXMinYCorner];


你所说的路径是什么意思?你能解释得更详细一点吗?对不起,回答错了-他问如何在不覆盖的情况下做到这一点drawRect@AshleyMillsOP问如何做到“…不覆盖drawRect或类似的东西…”这是相当模糊的。据我们所知,重写
-initWithCoder:
也可以称为“类似的东西”。我回答中的第二个(现在也是第三个)方法不需要重写任何东西。第一个是这样的,但我不认为这会让答案“错”。只是用这一个尝试了一下,但背景色现在不见了:(代码是你的代码的1:1…这太令人费解了!我创建了一个UIView子视图来测试它,它工作得很好。有人对此有问题吗?只是在左角附近?@你的布局是否更改了?例如,如果你将代码放在
UIViewController
viewDidLoad
中,视图的大小会被自动布局调整,然后它发生了。如果你将代码移动到
viewdilayoutsubviews
,那么问题就解决了。如何添加边框宽度和颜色?有什么好的理由你不想覆盖
drawRect
?因为这是我最不想做的事情…它太讨厌了,我认为有更好的方法来做。drawRect不是讨厌的,而是真正的东西!For任何想寻找一个同时支持边框的现代答案的人,我在下面添加了一个非常干净的解决方案-对于
界面生成器
唯一的解决方案看这里:谢谢你,好心的先生!我需要我的视图底部弯曲,你的代码工作得非常完美。即使我有一个tableView,我也不必用ContentView进行初始化尽管如此。如果(position==tableCellBound)对我有效,那么您可以在roundCorners函数中添加self.layer.masksToBounds=true,否?关于这一点的快速说明很好:它在
属性上,而不是直接在视图上(
视图.层
来自ViewController)。
import UIKit
import PlaygroundSupport

let wrapperView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 160))
wrapperView.backgroundColor = .lightGray

let roundedCornerView = UIView(frame: CGRect(x: 50, y: 50, width: 300, height: 60))
roundedCornerView.backgroundColor = .white

wrapperView.addSubview(roundedCornerView)

roundedCornerView.layer.cornerRadius = 10
roundedCornerView.layer.borderColor = UIColor.red.cgColor
roundedCornerView.layer.borderWidth = 1


// this is the key part - try out different corner combinations to achieve what you need
roundedCornerView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]


PlaygroundPage.current.liveView = wrapperView
[oCollectionViewCell.layer setMasksToBounds:YES];
[oCollectionViewCell.layer setCornerRadius:5.0];
[oCollectionViewCell.layer setMaskedCorners:kCALayerMinXMinYCorner|kCALayerMaxXMinYCorner];