我都用了UIBezierPath
和CAShapeLayer
前.但几乎每次都与填充路径中包含的对象一起使用颜色.但是我想这次填充颜色所包含的对象之外的颜色UIBezierPath
.
我刚刚编写并运行了以下简单的代码,试图让自己熟悉该fillRule
属性:
CAShapeLayer *myLayer = (CAShapeLayer*) self.layer; //size: 320 X 480
UIBezierPath *testPath = [UIBezierPath bezierPathWithOvalInRect:(CGRect){{100, 100}, 100, 100}]; //a simple circle
myLayer.fillRule = kCAFillRuleNonZero; // have tried this as well: kCAFillRuleEvenOdd;
myLayer.path = testPath.CGPath;
myLayer.fillColor = [UIColor whiteColor].CGColor;
Run Code Online (Sandbox Code Playgroud)
但是内部仍然填充了颜色.我想知道的是,我如何填充路径之外的颜色?如果我在fillRule
这里使用错误,我想知道是否有其他方法可以实现这一点.提前致谢.
我正在尝试实现一个循环指示器,随着值的变化,它会自动绘制动画.
我用CAShapeLayer
画画动画.到目前为止,我每次都从头开始绘制它,它按预期工作.现在我想让它更圆滑并向前绘制并"擦除",具体取决于新值是否大于或低于之前的值.我不确定如何实现擦除部分.有一个背景所以我不能只用白色画在上面.这是一张图片,可以更好地了解它的外观.
有关如何实现擦除部分的任何想法?在类似的问题上有一些关于SO的解决方案,但那些涉及没有动画.
我使用此代码绘制:
- (void)drawCircleAnimatedWithStartAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
color:(UIColor *)color
radius:(int)radius
lineWidth:(int)lineWidth {
CAShapeLayer *circle = [CAShapeLayer layer];
circle.name = @"circleLayer";
circle.path = ([UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius-1 startAngle:startAngle endAngle:endAngle clockwise:YES].CGPath);
// Configure the apperence of the circle
circle.fillColor = [UIColor clearColor].CGColor;
circle.strokeColor = [UIColor colorWithRed:19.0/255 green:167.0/255 blue:191.0/255 alpha:1].CGColor;
circle.lineWidth = lineWidth;
// Add to parent layer
for (CALayer *layer in self.circleView.layer.sublayers) {
if ([layer.name isEqualToString:@"circleLayer"]) {
[layer removeFromSuperlayer];
break;
}
}
[self.circleView.layer addSublayer:circle];
circle.zPosition = 1;
// Configure animation …
Run Code Online (Sandbox Code Playgroud)
我有一个奇怪的问题.虽然我确实阅读了很多关于如何做到这一点的教程,但最终结果只显示了贝塞尔线,而不是任何阴影.我的代码非常简单:
let borderLine = UIBezierPath()
borderLine.moveToPoint(CGPoint(x:0, y: y! - 1))
borderLine.addLineToPoint(CGPoint(x: x!, y: y! - 1))
borderLine.lineWidth = 2
UIColor.blackColor().setStroke()
borderLine.stroke()
let shadowLayer = CAShapeLayer()
shadowLayer.shadowOpacity = 1
shadowLayer.shadowOffset = CGSize(width: 0,height: 1)
shadowLayer.shadowColor = UIColor.redColor().CGColor
shadowLayer.shadowRadius = 1
shadowLayer.masksToBounds = false
shadowLayer.shadowPath = borderLine.CGPath
self.layer.addSublayer(shadowLayer)
Run Code Online (Sandbox Code Playgroud)
我做错了什么,因为我似乎没有看到任何错误,但当然我错了,因为没有出现阴影.函数是drawRect,基本的UIVIew没有任何额外的东西,x和y是框架的宽度和高度.
提前谢谢了!
我正在尝试画一个以逆时针方向 12 点钟开始和结束的圆圈。我遇到的问题是形状没有被绘制。我使用init(arcCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool)
路径初始化程序,如果我使用clockwise: true
,它就可以工作。如果startAngle
设置为0
和endAngle
to2 * .pi
它适用于clockwise: false
. clockwise: false
然而和的组合startAngle: -0.5 * .pi, endAngle: 1.5 * .pi
不起作用。这是有原因的吗?我该如何解决?
这个有效:
let shapeLayer = CAShapeLayer()
let arcCenter = view.center
let circularPath = UIBezierPath(arcCenter: arcCenter, radius: 100, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: false)
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 10
shapeLayer.lineCap = .round
shapeLayer.fillColor …
Run Code Online (Sandbox Code Playgroud) 这个问题很难用言语表达,但进一步解释情况应该会有所帮助。
使用下面的代码,我实质上是在屏幕上点击一个圆圈,以显示黑色 UIView 下方的内容。当我点击时,我将 CGPoint 记录在数组中以跟踪点击的位置。对于我随后进行的每次点击,我都会删除黑色 UIView 并从我正在跟踪的 CGPoints 数组中重新创建每个点击点,以便创建一个包含所有先前点的新蒙版。
结果是这样的:
我相信您已经可以发现我在问什么...如何避免在圆圈相交的地方遮罩反转?感谢您的帮助!
这是我的代码供参考:
class MiniGameShadOViewController: UIViewController {
//MARK: - DECLARATIONS
var revealRadius : CGFloat = 50
var tappedAreas : [CGPoint] = []
//Objects
@IBOutlet var shadedRegion: UIView!
//Gesture Recognizers
@IBOutlet var tapToReveal: UITapGestureRecognizer!
//MARK: - VIEW STATES
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - USER INTERACTIONS
@IBAction func regionTapped(_ sender: UITapGestureRecognizer) {
let tappedPoint = sender.location(in: view)
tappedAreas.append(tappedPoint) //Hold a list of all previously tapped points
//Clean up old …
Run Code Online (Sandbox Code Playgroud) 我无法在使用UIBezierpath绘制的线条中找到触摸点.CGPathContainPoint不适用于线路.请帮帮我
我想创建一个蒙版路径,其最终输出将是一个带凹面的角.
我已经创建了一个UIBezierPath
使用该-bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
方法并指定只需要对一个角进行舍入(在此示例中UIRectCornerBottomLeft
),我认为通过反转此路径,我应该得到首先要切割的内容.
为此,我正在尝试,-bezierPathByReversingPath
但它似乎没有任何区别(有或没有,因为我得到正常的bezier路径,而不是相反)
这是我到目前为止所尝试的:
UIView *vwTest = [[UIView alloc] init];
[vwTest setFrame:CGRectMake(100.0f, 100.0f, 100.0f, 100.0f)];
[vwTest setBackgroundColor:[UIColor redColor]];
[self.view addSubview:vwTest];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:vwTest.bounds
byRoundingCorners:UIRectCornerBottomLeft
cornerRadii:CGSizeMake(50.0f, 50.0f)];
//get reverse path but doesn't seem to work as I think it should
maskPath = [maskPath bezierPathByReversingPath];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
[maskLayer setFrame:vwTest.bounds];
[maskLayer setPath:maskPath.CGPath];
[vwTest.layer setMask:maskLayer];
[vwTest.layer setMasksToBounds:YES];
[vwTest setNeedsDisplay];
Run Code Online (Sandbox Code Playgroud)
根据下面的图像,我想要实现的是显示红色部分UIView
并消除其余区域.
暂时,我在subview上做subit,并将一个子视图的颜色与主视图的背景颜色同步(很糟糕,但至少我得到了所需的输出):
[self.view setBackgroundColor:[UIColor lightGrayColor]]; …
Run Code Online (Sandbox Code Playgroud) 我正在尝试为UIView创建一个图层蒙版,它将作为一个滑出面板服务器.我需要这个圆角右下角约50像素的效果.到目前为止,我已经能够通过创建一个具有清晰背景颜色的UIView xib和另一个较小的UIView(子视图)来实现这种效果,它在底部和右侧是50 px插入.我想在不使用较小的子视图的情况下实现此效果.换句话说,创建一个从底部和右侧插入50 px的蒙版,右下角有一个圆角.
当我在子视图上绘制蒙版时,它可以在我开始的任何屏幕方向上工作,但是当设备旋转时,我得到的结果确实不一致.在我的子视图类中,我有以下代码:
- (void)drawRect:(CGRect)rect
{
CAShapeLayer *maskLayer = [CAShapeLayer layer];
CGPathRef path = [[UIBezierPath bezierPathWithRoundedRect:[_subView bounds]
byRoundingCorners:UIRectCornerBottomRight
cornerRadii:(CGSize){150.0, 150.0}] CGPath];
[maskLayer setPath:path];
[_subView.layer setMask:maskLayer];
CGPathRelease(path);
}
Run Code Online (Sandbox Code Playgroud)
我不确定问题是什么,但是如果我可以通过使用一个带掩码的UIView来实现这个效果,似乎可能更容易处理它.以下是子视图的屏幕截图.显然,我对掩蔽技术有点新意.
图像中显示的灰色图案是主视图控制器,顶部是xib的UIView.通过将xib的主视图设置为具有清晰的背景颜色来实现透明度.
编辑这是在景观中打开时的视图.我将UIView的背景设置为白色,以表明它是在设备旋转时无法正确呈现的子视图.
旋转时,结果如下:
正如已经提到的,由于主视图渲染得当,似乎更好的方法是创建一个实现类似效果的蒙版,但不确定,这就是为什么我在这里!
我希望我已经足够清楚了.有人能帮忙吗?谢谢!
我正试图从图像的底部创建一个"揭示"效果.我认为这就像将anchorPoint设置为CGPointMake(0.5,1.0)或将contentsGravity设置为kCAGravityTop一样简单,但这些选项都不起作用.
我目前的代码有效,但从上到下有动画效果.这里有一个揭示的想法:http://giphy.com/gifs/xTiTnBzItdgaD1xHMc
我如何从头到尾进行此操作?
这是代码
let path = UIBezierPath(rect: CGRectMake(0, 0, imgEmptyBase.width, imgEmptyBase.height - 80))
let mask = CAShapeLayer()
mask.anchorPoint = CGPointMake(0.5, 1.0)
mask.path = path.CGPath
imgEmptyBase.layer.mask = mask
let anim = CABasicAnimation(keyPath: "path")
anim.fromValue = path.CGPath
anim.toValue = UIBezierPath(rect: imgEmptyBase.bounds).CGPath
anim.duration = 1.0
anim.fillMode = kCAFillModeForwards
anim.removedOnCompletion = false
imgEmptyBase.layer.mask.addAnimation(anim, forKey: "anim")
Run Code Online (Sandbox Code Playgroud) 我可以检测到这样的触摸CAShapeLayer(touchesEnded):
let touchLocation : CGPoint = (touch as! UITouch).locationInView(self.view)
for shape in shapes{
if CGPathContainsPoint(shape.path, nil, touchLocation, false){
print("Layer touch")
}
}
Run Code Online (Sandbox Code Playgroud)
我可以像这样动画CAShapeLayer的路径:
let newShapePath = UIBezierPath(arcCenter: toPoint, radius: 20, startAngle: CGFloat(0), endAngle: CGFloat(M_PI * 2), clockwise: true).CGPath
// animate the `path`
let animation = CABasicAnimation(keyPath: "path")
animation.toValue = newShapePath
animation.duration = CFTimeInterval(duration)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
animation.fillMode = kCAFillModeBoth
animation.removedOnCompletion = false
shape.addAnimation(animation, forKey: animation.keyPath)
Run Code Online (Sandbox Code Playgroud)
但是当动画发生时,CAShapeLayer上没有检测到触摸.是否可以在动画路径时检测CAShapeLayer上的触摸?
cashapelayer ×10
ios ×7
swift ×5
uibezierpath ×5
objective-c ×2
uiview ×2
animation ×1
calayer ×1
drawing ×1
mask ×1
overlap ×1
overlay ×1
shadow ×1