Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
IOS:可以在每个角使用不同的值使半径变圆_Ios_Layer_Uibezierpath - Fatal编程技术网

IOS:可以在每个角使用不同的值使半径变圆

IOS:可以在每个角使用不同的值使半径变圆,ios,layer,uibezierpath,Ios,Layer,Uibezierpath,我想用这样的值使我的ui视图更圆 左上半径:20右下角半径:5左下半径:5和右上角半径:10 //For rounder `UIRectCornerBottomLeft & UIRectCornerBottomRight` I use UIBezierPath *maskPath0 = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCorne

我想用这样的值使我的
ui视图更圆

左上半径:20右下角半径:5
左下半径:5和<代码>右上角半径:10

   //For rounder `UIRectCornerBottomLeft & UIRectCornerBottomRight` I use

    UIBezierPath *maskPath0 = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(5.0, 5.0)];

    CAShapeLayer *maskLayer0 = [[CAShapeLayer alloc] init];
    maskLayer0.frame = self.bounds;
    maskLayer0.path  = maskPath0.CGPath;
    self.messageView.layer.mask = maskLayer0;


    //For rounder `TopRight` I use

    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerTopRight) cornerRadii:CGSizeMake(10.0, 10.0)];

    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = self.bounds;
    maskLayer.path  = maskPath.CGPath;
    self.messageView.layer.mask = maskLayer;


    //For rounder `TopLeft` I use

    UIBezierPath *maskPath2 = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerTopLeft) cornerRadii:CGSizeMake(20.0, 20.0)];

    CAShapeLayer *maskLayer2 = [[CAShapeLayer alloc] init];
    maskLayer2.frame = self.bounds;
    maskLayer2.path  = maskPath2.CGPath;
    self.messageView.layer.mask = maskLayer2;
但是我得到的结果是角半径为20的视图。
我怎样才能达到这个目标?任何帮助都将不胜感激。

UIBezierPath
没有这种方法。但您可以使用一系列的
addLineToPoint
addarchwithcenter
方法来执行此操作:

let minx = CGRectGetMinX(rect)
let miny = CGRectGetMinY(rect)
let maxx = CGRectGetMaxX(rect)
let maxy = CGRectGetMaxY(rect)

let path = UIBezierPath()
path.moveToPoint(CGPointMake(minx + topLeftRadius, miny))
path.addLineToPoint(CGPointMake(maxx - topRightRadius, miny))
path.addArcWithCenter(CGPointMake(maxx - topRightRadius, miny + topRightRadius), radius: topRightRadius, startAngle:3 * M_PI_2, endAngle: 0, clockwise: true)
path.addLineToPoint(CGPointMake(maxx, maxy - bottomRightRadius))
path.addArcWithCenter(CGPointMake(maxx - bottomRightRadius, maxy - bottomRightRadius), radius: bottomRightRadius, startAngle: 0, endAngle: M_PI_2, clockwise: true)
path.addLineToPoint(CGPointMake(minx + bottomLeftRadius, maxy))
path.addArcWithCenter(CGPointMake(minx + bottomLeftRadius, maxy - bottomLeftRadius), radius: bottomLeftRadius, startAngle: M_PI_2, endAngle: M_PI, clockwise: true)
path.addLineToPoint(CGPointMake(minx, miny + topLeftRadius))
path.addArcWithCenter(CGPointMake(minx + topLeftRadius, miny + topLeftRadius), radius: topLeftRadius, startAngle: M_PI, endAngle: 3 * M_PI_2, clockwise: true)
path.closePath()
对于Obj-C:

CGFloat topLeftRadius = 20;
CGFloat topRightRadius = 10;
CGFloat bottomRightRadius = 5;
CGFloat bottomLeftRadius = 5;

CGFloat minx = CGRectGetMinX(self.messageView.bounds);
CGFloat miny = CGRectGetMinY(self.messageView.bounds);
CGFloat maxx = CGRectGetMaxX(self.messageView.bounds);
CGFloat maxy = CGRectGetMaxY(self.messageView.bounds);

UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(minx + topLeftRadius, miny)];
[path addLineToPoint:CGPointMake(maxx - topRightRadius, miny)];
[path addArcWithCenter:CGPointMake(maxx - topRightRadius, miny + topRightRadius) radius: topRightRadius startAngle: 3 * M_PI_2 endAngle: 0 clockwise: YES];
[path addLineToPoint:CGPointMake(maxx, maxy - bottomRightRadius)];
[path addArcWithCenter:CGPointMake(maxx - bottomRightRadius, maxy - bottomRightRadius) radius: bottomRightRadius startAngle: 0 endAngle: M_PI_2 clockwise: YES];
[path addLineToPoint:CGPointMake(minx + bottomLeftRadius, maxy)];
[path addArcWithCenter:CGPointMake(minx + bottomLeftRadius, maxy - bottomLeftRadius) radius: bottomLeftRadius startAngle: M_PI_2 endAngle:M_PI clockwise: YES];
[path addLineToPoint:CGPointMake(minx, miny + topLeftRadius)];
[path addArcWithCenter:CGPointMake(minx + topLeftRadius, miny + topLeftRadius) radius: topLeftRadius startAngle: M_PI endAngle:3 * M_PI_2 clockwise: YES];
[path closePath];

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.path = path.CGPath;
self.messageView.layer.mask = maskLayer;

下面是一个UIBezierPath类别,它按照一些现有初始值设定项的模式执行您想要的操作:

extension UIBezierPath {
    public convenience init(roundedRect rect: CGRect, topLeftRadius: CGFloat?, topRightRadius: CGFloat?, bottomLeftRadius: CGFloat?, bottomRightRadius: CGFloat?) {
        self.init()

        assert(((bottomLeftRadius ?? 0) + (bottomRightRadius ?? 0)) <= rect.size.width)
        assert(((topLeftRadius ?? 0) + (topRightRadius ?? 0)) <= rect.size.width)
        assert(((topLeftRadius ?? 0) + (bottomLeftRadius ?? 0)) <= rect.size.height)
        assert(((topRightRadius ?? 0) + (bottomRightRadius ?? 0)) <= rect.size.height)

        // corner centers
        let tl = CGPoint(x: rect.minX + (topLeftRadius ?? 0), y: rect.minY + (topLeftRadius ?? 0))
        let tr = CGPoint(x: rect.maxX - (topRightRadius ?? 0), y: rect.minY + (topRightRadius ?? 0))
        let bl = CGPoint(x: rect.minX + (bottomLeftRadius ?? 0), y: rect.maxY - (bottomLeftRadius ?? 0))
        let br = CGPoint(x: rect.maxX - (bottomRightRadius ?? 0), y: rect.maxY - (bottomRightRadius ?? 0))

        //let topMidpoint = CGPoint(rect.midX, rect.minY)
        let topMidpoint = CGPoint(x: rect.midX, y: rect.minY)

        makeClockwiseShape: do {
            self.move(to: topMidpoint)

            if let topRightRadius = topRightRadius {
                self.addLine(to: CGPoint(x: rect.maxX - topRightRadius, y: rect.minY))
                self.addArc(withCenter: tr, radius: topRightRadius, startAngle: -CGFloat.pi/2, endAngle: 0, clockwise: true)
            }
            else {
                self.addLine(to: tr)
            }

            if let bottomRightRadius = bottomRightRadius {
                self.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - bottomRightRadius))
                self.addArc(withCenter: br, radius: bottomRightRadius, startAngle: 0, endAngle: CGFloat.pi/2, clockwise: true)
            }
            else {
                self.addLine(to: br)
            }

            if let bottomLeftRadius = bottomLeftRadius {
                self.addLine(to: CGPoint(x: rect.minX + bottomLeftRadius, y: rect.maxY))
                self.addArc(withCenter: bl, radius: bottomLeftRadius, startAngle: CGFloat.pi/2, endAngle: CGFloat.pi, clockwise: true)
            }
            else {
                self.addLine(to: bl)
            }

            if let topLeftRadius = topLeftRadius {
                self.addLine(to: CGPoint(x: rect.minX, y: rect.minY + topLeftRadius))
                self.addArc(withCenter: tl, radius: topLeftRadius, startAngle: CGFloat.pi, endAngle: -CGFloat.pi/2, clockwise: true)
            }
            else {
                self.addLine(to: tl)
            }

            self.close()
        }
    }
}
扩展UIBezierPath{ 公共便利初始化(roundedRect-rect:CGRect,topLeftRadius:CGFloat?,topRightRadius:CGFloat?,bottomLeftRadius:CGFloat?,bottomRightRadius:CGFloat?){ self.init()
断言((bottomLeftRadius±0)+(bottomRightRadius±0))Swift 5 UIView扩展版本@Mikhail Grebionkin的答案:

extension UIView {

    func makeCustomRound(topLeft: CGFloat = 0, topRight: CGFloat = 0, bottomLeft: CGFloat = 0, bottomRight: CGFloat = 0) {
        let minX = bounds.minX
        let minY = bounds.minY
        let maxX = bounds.maxX
        let maxY = bounds.maxY

        let path = UIBezierPath()
        path.move(to: CGPoint(x: minX + topLeft, y: minY))
        path.addLine(to: CGPoint(x: maxX - topRight, y: minY))
        path.addArc(withCenter: CGPoint(x: maxX - topRight, y: minY + topRight), radius: topRight, startAngle:CGFloat(3 * Double.pi / 2), endAngle: 0, clockwise: true)
        path.addLine(to: CGPoint(x: maxX, y: maxY - bottomRight))
        path.addArc(withCenter: CGPoint(x: maxX - bottomRight, y: maxY - bottomRight), radius: bottomRight, startAngle: 0, endAngle: CGFloat(Double.pi / 2), clockwise: true)
        path.addLine(to: CGPoint(x: minX + bottomLeft, y: maxY))
        path.addArc(withCenter: CGPoint(x: minX + bottomLeft, y: maxY - bottomLeft), radius: bottomLeft, startAngle: CGFloat(Double.pi / 2), endAngle: CGFloat(Double.pi), clockwise: true)
        path.addLine(to: CGPoint(x: minX, y: minY + topLeft))
        path.addArc(withCenter: CGPoint(x: minX + topLeft, y: minY + topLeft), radius: topLeft, startAngle: CGFloat(Double.pi), endAngle: CGFloat(3 * Double.pi / 2), clockwise: true)
        path.close()

        let mask = CAShapeLayer()
        mask.path = path.cgPath
        layer.mask = mask
    }
}


它是swift,对吗?我是iOS新手,我不知道swift。如果你不介意的话,你可以添加一个objective-c版本。非常感谢;)是的,它是swift。我已经将它翻译成Obj-c。希望我没有遗漏任何“;”或“[]“非常感谢。但是我现在必须回家,我明天会检查。然后我会通知你;)我在objective-c中尝试了你的解决方案,但不幸的是,视图消失了:((我已经检查过并获得了成功的结果。你用什么作为矩形?你需要使用
self.messageView.bounds
。请检查更新的Obj-C代码。你需要使用同一个对象添加所有的角半径,到目前为止,你的最后一个对象正在应用角半径。@VatsalK你是对的,但现在我不知道如何在同一个对象中添加它,可以吗您可以用代码进行更多描述。非常感谢您,如果您需要根据自己的要求绘制形状,您可以参考此图,也可以制作相同形状的图像,并将图像设置为背景。在这个较老的问题上,值得注意的是,最新的答案-我向其发送了一份赏金-非常完美,只需将其粘贴进来,而不做任何其他操作。发送y你是赏金!:)顺便说一句,我修复了一个小语法错误。