English 中文(简体)
UIBezierPath Subtract Path
原标题:UIBezierPath Subtract Path

通过使用<条码>[IDBezierPath bezierPathWithRoundedRect:byRoundingCorners:Iser Radii:],我得以形成一种四舍五入的观点,例如:

rounded view

我如何能够从这条道路上(或以某种方式)绕过另一条道路,从而形成这样的道路:

https://i.stack.imgur.com/Rb82R.png” alt=“subtracted view”/>

Is there any way I can do something like this? Pseudocode:

UIBezierPath *bigMaskPath = [UIBezierPath bezierPathWithRoundedRect:bigView.bounds 
                                 byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight)
                                       cornerRadii:CGSizeMake(18, 18)];
UIBezierPath *smallMaskPath = [UIBezierPath bezierPathWithRoundedRect:smalLView.bounds 
                                     byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight)
                                           cornerRadii:CGSizeMake(18, 18)];

UIBezierPath *finalPath = [UIBezierPath pathBySubtractingPath:smallMaskPath fromPath:bigMaskPath];
最佳回答

如果你想要走下一条被拖走的道路,你自己就走了。 Apple果树脂中含有一种反应器,即从另一条途径(或只是中风)中回收。

如果你只想填满(如您的榜样形象),你就能够使用滑坡道路。 不过,你们必须使用一个trick子。 当你在滑坡道路上添加一条路时,新的滑坡道路是旧的滑坡道和附加道路的intersection。 因此,如果你只添加<条码>小马斯克帕塔,则你将最终在<条码>中填满区域,而这正是你想要的。

你们需要做的是,将现有的剪切路径与<条码>中文本<>>/m>连接起来。 幸运的是,你能够非常容易地利用 even夜规则。 http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_paths/dq_paths.html#/apple_ref/doc/uid/TP30001066-CH211-TPXREF106, Quartz 2D Program Guide

基本想法是,我们开辟一条有两条子的复合道路:smallMaskPath和一条完全随附<条码>的大型试金星,以及你希望填满的所有其他星。 由于偶然规则,在<条码>上的每一张钢材都将在复合道路之外处理,在<条码>上外的每张钢材都将在复合道路内处理。

So let s create this compound path. We ll start with the huge rectangle. And there is no rectangle more huge than the infinite rectangle:

UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:CGRectInfinite];

现在,我们通过添加<条码>中小马Mas/条码>,使之成为一个复合途径:

[clipPath appendPath:smallMaskPath];

接下来,我们确定了使用“ even”规则的道路:

clipPath.usesEvenOddFillRule = YES;

在我们走上这条道路之前,我们应当拯救图象国家,以便我们能够在我们重新努力时打破通往滑坡的道路的转变:

CGContextSaveGState(UIGraphicsGetCurrentContext()); {

我们现在可以修改滑坡道路:

    [clipPath addClip];

我们可以填写<代码>bigMaskPath:

    [[UIColor orangeColor] setFill];
    [bigMaskPath fill];

最后,我们恢复图形状态,改变lipp路:

} CGContextRestoreGState(UIGraphicsGetCurrentContext());

在这里,如果你想要复制/复制该守则:

UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:CGRectInfinite];
[clipPath appendPath:smallMaskPath];
clipPath.usesEvenOddFillRule = YES;

CGContextSaveGState(UIGraphicsGetCurrentContext()); {
    [clipPath addClip];
    [[UIColor orangeColor] setFill];
    [bigMaskPath fill];
} CGContextRestoreGState(UIGraphicsGetCurrentContext());
问题回答

实际情况是,大多数案件都比较简单,例如:

path.append(cutout.reversing())

这是因为缺省填充规则是non-zero风化规则

应当这样做,并像你一样调整规模:

CGRect outerRect = {0, 0, 200, 200};
CGRect innerRect  = CGRectInset(outerRect,  30, 30);

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:outerRect cornerRadius:10];

[path appendPath:[UIBezierPath bezierPathWithRoundedRect:innerRect cornerRadius:5]];
path.usesEvenOddFillRule = YES;

[[UIColor orangeColor] set];
[path fill];

取得你之后作用的另一个真正简单的办法是,只提外部圆点,改变颜色,从内部取而代之。

借助@Patrick Pijnappel的答复,你可以为快速检测准备试验游戏场。

import UIKit
import PlaygroundSupport

let view = UIView(frame: CGRect(x: 0, y: 0, width: 375, height: 647))
view.backgroundColor = UIColor.green

let someView = UIView(frame: CGRect(x:50, y: 50, width:250, height:250))
someView.backgroundColor = UIColor.red
view.addSubview(someView)

let shapeLayer = CAShapeLayer()
shapeLayer.frame = someView.bounds
shapeLayer.path = UIBezierPath(roundedRect: someView.bounds, 
                               byRoundingCorners: [UIRectCorner.bottomLeft,UIRectCorner.bottomRight] ,
                                cornerRadii: CGSize(width: 5.0, height: 5.0)).cgPath

someView.layer.mask = shapeLayer
someView.layer.masksToBounds = true

let rect = CGRect(x:0, y:0, width:200, height:100)
let cornerRadius:CGFloat = 5
let subPathSideSize:CGFloat = 25

let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
let leftSubPath = UIBezierPath(arcCenter: CGPoint(x:0, y:rect.height / 2), 
                                radius: subPathSideSize / 2, startAngle:  CGFloat(Double.pi / 2), endAngle: CGFloat(Double.pi + Double.pi / 2), clockwise: false)
leftSubPath.close()

let rightSubPath = UIBezierPath(arcCenter: CGPoint(x:rect.width, y:rect.height / 2), 
                               radius: subPathSideSize / 2, startAngle:  CGFloat(Double.pi / 2), endAngle: CGFloat(Double.pi + Double.pi / 2), clockwise: true)
rightSubPath.close()

path.append(leftSubPath)
path.append(rightSubPath.reversing())
path.append(path)

let mask = CAShapeLayer()
mask.frame = shapeLayer.bounds
mask.path = path.cgPath

someView.layer.mask = mask 

view
PlaygroundPage.current.liveView = view

“entergraph

“enterhchr

I ve been beating my head against the wall trying to figure out how to do this with multiple overlapping CGPaths. If you overlap more than once, it refills with the solutions provided above. It turns out the way to truly attain a subtract effect with multiple overlapping paths is to just set the context s blend mode to clear.

CGContextSetBlendMode(ctx, kCGBlendModeClear);

Patrick provided an improvement/alternative to user NSResponder s answer by using the non-zero winding rule. Here is a full implementation in Swift for anyone that is looking for an expanded answer.

UIGraphicsBeginImageContextWithOptions(CGSize(width: 200, height: 200), false, 0.0)
let context = UIGraphicsGetCurrentContext()

let rectPath = UIBezierPath(roundedRect: CGRectMake(0, 0, 200, 200), cornerRadius: 10)
var cutoutPath = UIBezierPath(roundedRect: CGRectMake(30, 30, 140, 140), cornerRadius: 10)

rectPath.appendPath(cutoutPath.bezierPathByReversingPath())

UIColor.orangeColor().set()
outerForegroundPath.fill()

let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

此处为

你们可以把这一点放在一个故事板上,以了解和发挥产出的作用。

“结果”/

这里有两个透明的观点漏洞:

“enterography

@IBDesignable
class HoleView: UIView {
    
    @IBInspectable
    var radius1: CGFloat = 10 { didSet { updateMask() } }
    
    @IBInspectable
    var XPositionPercent1: CGFloat = 90 { didSet { updateMask() } }
    
    @IBInspectable
    var YPositionPercent1: CGFloat = 50 { didSet { updateMask() } }
    
    
    @IBInspectable
    var radius2: CGFloat = 10 { didSet { updateMask() } }
    
    @IBInspectable
    var XPositionPercent2: CGFloat = 10 { didSet { updateMask() } }
    
    @IBInspectable
    var YPositionPercent2: CGFloat = 50 { didSet { updateMask() } }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        updateMask()
    }
    
    private func updateMask() {
        
        let path = UIBezierPath(rect: bounds)
        path.usesEvenOddFillRule = false
        
        
        // MARK: Hole 1
        let XPos1 = (bounds.width * XPositionPercent1) / 100
        let YPos1 = (bounds.height * YPositionPercent1) / 100
        let center1 = CGPoint(x: XPos1, y: YPos1)
        
        let hole1 = UIBezierPath(arcCenter: center1,
                                 radius: radius1,
                                 startAngle: 0,
                                 endAngle: 2 * .pi,
                                 clockwise: true)
        path.append(hole1)
        
        // MARK: Hole 2
        let XPos2 = (bounds.width * XPositionPercent2) / 100
        let YPos2 = (bounds.height * YPositionPercent2) / 100
        let center2 = CGPoint(x: XPos2, y: YPos2)
        let hole2 = UIBezierPath(arcCenter: center2,
                                 radius: radius2,
                                 startAngle: 0,
                                 endAngle: 2 * .pi,
                                 clockwise: true)
        path.append(hole2)
        
        
        
        let mask1 = CAShapeLayer()
        mask1.fillRule = .evenOdd
        mask1.path = path.cgPath
        
        layer.mask = mask1
    }
}

Instead of subtracting, I was able to solve by creating a CGPath using CGPathAddLineToPoint and CGPathAddArcToPoint. This can also be done with a UIBiezerPath with similar code.





相关问题
Code sign Error

I have created a new iPhone application.I have two mach machines. I have created the certificate for running application in iPhone in one mac. Can I use the other mac for running the application in ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

将音频Clips从Peter改为服务器

我不禁要问,那里是否有任何实例表明从Peit向服务器发送音响。 I m不关心电话或SIP风格的解决办法,只是一个简单的袖珍流程......

• 如何将搜查线重新定位?

我正试图把图像放在搜索条左边。 但是,问题始于这里,搜索条线不能重新布署。

热门标签