【问题标题】:Just two rounded corners? [duplicate]只有两个圆角? [复制]
【发布时间】:2011-06-18 05:29:44
【问题描述】:

在我的 iPad 应用程序中,我希望在用户单击按钮时在主视图中显示第二个视图。新视图将比第一个视图小,并在显示时使背景变暗。我希望新视图的前两个角看起来是圆形的,但是使用cornerRadius 会将它们全部设置为圆形。我怎样才能使两个角变成圆角?

【问题讨论】:

    标签: iphone objective-c ipad rounded-corners


    【解决方案1】:

    您必须在 drawRect: 中执行此操作。我实际上修改了经典的 addRoundedRectToPath: 以便它需要一个位图并圆你请求的角:

    static void addRoundedRectToPath(CGContextRef context, CGRect rect, float radius, UIImageRoundedCorner cornerMask)
    {
        CGContextMoveToPoint(context, rect.origin.x, rect.origin.y + radius);
        CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height - radius);
        if (cornerMask & UIImageRoundedCornerTopLeft) {
            CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, 
                            radius, M_PI, M_PI / 2, 1);
        }
        else {
            CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height);
            CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y + rect.size.height);
        }
    
        CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, 
                              rect.origin.y + rect.size.height);
    
        if (cornerMask & UIImageRoundedCornerTopRight) {
            CGContextAddArc(context, rect.origin.x + rect.size.width - radius, 
                            rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);
        }
        else {
            CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
            CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - radius);
        }
    
        CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius);
    
        if (cornerMask & UIImageRoundedCornerBottomRight) {
            CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, 
                            radius, 0.0f, -M_PI / 2, 1);
        }
        else {
            CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y);
            CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, rect.origin.y);
        }
    
        CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y);
    
        if (cornerMask & UIImageRoundedCornerBottomLeft) {
            CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + radius, radius, 
                            -M_PI / 2, M_PI, 1);
        }
        else {
            CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y);
            CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + radius);
        }
    
        CGContextClosePath(context);
    }
    

    这需要一个位掩码(我将其称为 UIImageRoundedCorner,因为我是为图像执行此操作,但您可以随便调用它),然后根据您想要圆角的角构建路径。然后将该路径应用到 drawRect 中的视图:

    CGContextBeginPath(context);
    addRoundedRectToPath(context, rect, radius, yourMask);
    CGContextClosePath(context);
    CGContextClip(context);
    

    正如我所说,我是为 UIImages 执行此操作的,因此我的代码并未完全设置为用于 drawRect:,但它应该很容易适应它。你基本上只是建立一个路径,然后将上下文剪辑到它。

    编辑:为了解释位掩码部分,它只是一个枚举:

    typedef enum {
        UIImageRoundedCornerTopLeft = 1,
        UIImageRoundedCornerTopRight = 1 << 1,
        UIImageRoundedCornerBottomRight = 1 << 2,
        UIImageRoundedCornerBottomLeft = 1 << 3
    } UIImageRoundedCorner;
    

    通过这种方式,您可以将事物组合在一起以形成标识角的位掩码,因为枚举的每个成员都代表位掩码中 2 的不同幂。

    很久以后编辑: 我发现了一种使用UIBezierPathbezierPathWithRoundedRect:byRoundingCorners:cornerRadii: 的更简单方法。只需在您的上下文中使用贝塞尔路径对象的CGPath

    【讨论】:

    • 很好的答案!只需要它的帮助来实现它。首先,如何制作自己的位掩码?
    • 编辑答案以解释枚举。
    • 我的答案是为了采取你想要的任何角落。如果您只需要前两个角而不关心其他角,您可以编辑位掩码废话,只使用与您需要圆角的角对应的两个部分。
    • 好的。全部插上,但没有用。你给我的第二个代码块是 CGContextBeginPath(context);这样的drawRect:方法对吗?它说在您创建 CGRect rect 的那一行,您正在重新定义 rect(因为它是 drawRect 的参数:)。我应该做什么?此外,更改 rect 的名称也无济于事。我对 drawRect: 的实际工作原理有点困惑,所以我不太确定出了什么问题。
    • 对不起,我只是复制/粘贴的错。 drawRect: 是在屏幕上绘制视图时调用的内容。 drawRect: 的参数是正在绘制的视图的区域。您可以直接将该矩形传递给 addRoundedRectToPath,因为您想要圆整整个绘制区域的顶部两个角。我将编辑我的答案以删除 rect 重新定义,就好像它在 drawRect:.
    【解决方案2】:

    在目标 C 中

       // Create the path (with only the top-left corner rounded)
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds 
                              byRoundingCorners:UIRectCornerTopLeft| UIRectCornerTopRight
                              cornerRadii:CGSizeMake(10.0, 10.0)];
    // Create the shape layer and set its path
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = imageView.bounds;
    maskLayer.path = maskPath.CGPath;
    // Set the newly created shape layer as the mask for the image view's layer
    imageView.layer.mask = maskLayer;
    

    这是另一种使用顶部圆角的方法。 Round two corners in UIView

    在斯威夫特!!!

    myView.clipsToBounds = true
    myView.layer.cornerRadius = 10
    myView.layer.maskedCorners = [.layerMinXMinYCorner,.layerMaxXMinYCorner]
    

    【讨论】:

    • 没问题..非常感谢
    • +1.. 最佳答案!!!!
    • @Sachin 只是复制粘贴别人的答案并将其作为自己的答案传递出去有点粗鲁。您至少可以添加指向我原始答案的链接:stackoverflow.com/a/5826698/429427
    • 导致autolayaout功能错误
    • @jose920405 我知道这个答案很旧,但我想补充一点,最好的方法是在 UIView 的 drawRect(rect: CGRect) 中使用该代码。因此,我将 imageView 子类化并实现 drawRect 并将该代码复制到 drawRect 函数中(不要忘记调用 super.drawRect !)
    【解决方案3】:

    Tomek Kuźma 的出色工作。这是满足您要求的新 TKRoundedView 类。
    仅此参数即可满足您的要求。

    TKRoundedView *view = [[TKRoundedView alloc] initWithFrame:frame];
    view.roundedCorners = TKRoundedCornerTopLeft | TKRoundedCornerTopRight;
    

    但它还提供以下额外功能。

    TKRoundedView *view = [[TKRoundedView alloc] initWithFrame:frame];
    view.roundedCorners = TKRoundedCornerTopLeft
    view.borderColor = [UIColor greenColor];
    view.fillColor = [UIColor whiteColor];
    view.drawnBordersSides = TKDrawnBorderSidesLeft | TKDrawnBorderSidesTop;
    view.borderWidth = 5.0f;
    view.cornerRadius = 15.0f;
    

    请查看示例项目的以下链接
    https://github.com/mapedd/TKRoundedView

    【讨论】:

    • ^ 太好了!非常适合自动布局。
    猜你喜欢
    • 2021-10-02
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 2015-06-19
    相关资源
    最近更新 更多