为了账号安全,请及时绑定邮箱和手机立即绑定

在UIView中的两个角

在UIView中的两个角

iOS
富国沪深 2019-10-15 09:49:57
不久前,我发布了一个关于仅将视图的两个角取整的问题,并获得了不错的答复,但是在实现它时遇到了问题。这是我的drawRect:方法:- (void)drawRect:(CGRect)rect {    //[super drawRect:rect]; <------Should I uncomment this?    int radius = 5;    CGContextRef context = UIGraphicsGetCurrentContext();    CGContextBeginPath(context);    CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, radius, M_PI, M_PI / 2, 1);    CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);    CGContextClosePath(context);    CGContextClip(context);}该方法正在被调用,但似乎并不影响视图的结果。有什么想法吗?
查看完整描述

3 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

iOS 11中引入的CACornerMask可帮助在视图层中定义左上,右上,左下,右下。以下是使用示例。


在这里,我尝试仅舍入两个上角:


myView.clipsToBounds = true

myView.layer.cornerRadius = 10

myView.layer.maskedCorners = [.layerMinXMinYCorner,.layerMaxXMinYCorner]

提前致谢。


仅供参考: 

//img1.sycdn.imooc.com//5da525dc0001f4ad03930180.jpg

查看完整回答
反对 回复 2019-10-15
?
POPMUISE

TA贡献1765条经验 获得超5个赞

据我所知,如果还需要遮罩子视图,则可以使用CALayer遮罩。有两种方法可以做到这一点。第一个比较优雅,第二个是一种解决方法:-),但它也很快。两者都是基于CALayer遮罩的。去年,我在几个项目中都使用了这两种方法,然后希望您能找到有用的东西。


解决方案1

首先,我创建了此函数以动态生成UIImage带有所需圆角的图像蒙版()。此函数本质上需要5个参数:图像的边界和4个角半径(左上,右上,左下和右下)。



static inline UIImage* MTDContextCreateRoundedMask( CGRect rect, CGFloat radius_tl, CGFloat radius_tr, CGFloat radius_bl, CGFloat radius_br ) {  


    CGContextRef context;

    CGColorSpaceRef colorSpace;


    colorSpace = CGColorSpaceCreateDeviceRGB();


    // create a bitmap graphics context the size of the image

    context = CGBitmapContextCreate( NULL, rect.size.width, rect.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast );


    // free the rgb colorspace

    CGColorSpaceRelease(colorSpace);    


    if ( context == NULL ) {

        return NULL;

    }


    // cerate mask


    CGFloat minx = CGRectGetMinX( rect ), midx = CGRectGetMidX( rect ), maxx = CGRectGetMaxX( rect );

    CGFloat miny = CGRectGetMinY( rect ), midy = CGRectGetMidY( rect ), maxy = CGRectGetMaxY( rect );


    CGContextBeginPath( context );

    CGContextSetGrayFillColor( context, 1.0, 0.0 );

    CGContextAddRect( context, rect );

    CGContextClosePath( context );

    CGContextDrawPath( context, kCGPathFill );


    CGContextSetGrayFillColor( context, 1.0, 1.0 );

    CGContextBeginPath( context );

    CGContextMoveToPoint( context, minx, midy );

    CGContextAddArcToPoint( context, minx, miny, midx, miny, radius_bl );

    CGContextAddArcToPoint( context, maxx, miny, maxx, midy, radius_br );

    CGContextAddArcToPoint( context, maxx, maxy, midx, maxy, radius_tr );

    CGContextAddArcToPoint( context, minx, maxy, minx, midy, radius_tl );

    CGContextClosePath( context );

    CGContextDrawPath( context, kCGPathFill );


    // Create CGImageRef of the main view bitmap content, and then

    // release that bitmap context

    CGImageRef bitmapContext = CGBitmapContextCreateImage( context );

    CGContextRelease( context );


    // convert the finished resized image to a UIImage 

    UIImage *theImage = [UIImage imageWithCGImage:bitmapContext];

    // image is retained by the property setting above, so we can 

    // release the original

    CGImageRelease(bitmapContext);


    // return the image

    return theImage;

}  

现在,您只需要几行代码。我把东西在我的viewController viewDidLoad的方法,因为它的速度更快,但你可以在自定义也用它UIView与layoutSubviews实例方法。




- (void)viewDidLoad {


    // Create the mask image you need calling the previous function

    UIImage *mask = MTDContextCreateRoundedMask( self.view.bounds, 50.0, 50.0, 0.0, 0.0 );

    // Create a new layer that will work as a mask

    CALayer *layerMask = [CALayer layer];

    layerMask.frame = self.view.bounds;       

    // Put the mask image as content of the layer

    layerMask.contents = (id)mask.CGImage;       

    // set the mask layer as mask of the view layer

    self.view.layer.mask = layerMask;              


    // Add a backaground color just to check if it works

    self.view.backgroundColor = [UIColor redColor];

    // Add a test view to verify the correct mask clipping

    UIView *testView = [[UIView alloc] initWithFrame:CGRectMake( 0.0, 0.0, 50.0, 50.0 )];

    testView.backgroundColor = [UIColor blueColor];

    [self.view addSubview:testView];

    [testView release];


    [super viewDidLoad];

}

解决方案2

这个解决方案有点“肮脏”。本质上,您可以使用所需的圆角(所有角)创建遮罩层。然后,应通过角半径的值增加蒙版层的高度。这样,底部的圆角被隐藏了,您只能看到上面的圆角。我把代码只是在viewDidLoad方法,因为它的速度更快,但你可以在自定义也用它UIView与layoutSubviews实例方法。


  


- (void)viewDidLoad {


    // set the radius

    CGFloat radius = 50.0;

    // set the mask frame, and increase the height by the 

    // corner radius to hide bottom corners

    CGRect maskFrame = self.view.bounds;

    maskFrame.size.height += radius;

    // create the mask layer

    CALayer *maskLayer = [CALayer layer];

    maskLayer.cornerRadius = radius;

    maskLayer.backgroundColor = [UIColor blackColor].CGColor;

    maskLayer.frame = maskFrame;


    // set the mask

    self.view.layer.mask = maskLayer;


    // Add a backaground color just to check if it works

    self.view.backgroundColor = [UIColor redColor];

    // Add a test view to verify the correct mask clipping

    UIView *testView = [[UIView alloc] initWithFrame:CGRectMake( 0.0, 0.0, 50.0, 50.0 )];

    testView.backgroundColor = [UIColor blueColor];

    [self.view addSubview:testView];

    [testView release];


    [super viewDidLoad];

}

希望这可以帮助。再见!


查看完整回答
反对 回复 2019-10-15
  • 3 回答
  • 0 关注
  • 561 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信