Itz*_*984 63 iphone objective-c uiview ios uibezierpath
我UIView
在运行时添加了代码.
我想画一个UIBezierPath
,但这是否意味着我必须覆盖drawRect
UIView?
或者是否有其他方式在定制上绘制它UIView
?
以下是生成以下内容的代码UIView
:
UIView* shapeView = [[UIView alloc]initWithFrame:CGRectMake(xOrigin,yOrigin+(i*MENU_BLOCK_FRAME_HEIGHT), self.shapeScroll.frame.size.width, MENU_BLOCK_FRAME_HEIGHT)];
shapeView.clipsToBounds = YES;
Run Code Online (Sandbox Code Playgroud)
以下是创建和返回的函数UIBezierPath
:
- (UIBezierPath*)createPath
{
UIBezierPath* path = [[UIBezierPath alloc]init];
[path moveToPoint:CGPointMake(100.0, 50.0)];
[path addLineToPoint:CGPointMake(200.0,50.0)];
[path addLineToPoint:CGPointMake(200.0, 200.0)];
[path addLineToPoint:CGPointMake(100.0, 200.0)];
[path closePath];
return path;
}
Run Code Online (Sandbox Code Playgroud)
Sur*_*gch 234
不久前,我甚至不知道如何发音Bézier,更不用说知道如何使用Bézier路径来制作自定义形状.以下是我所学到的.事实证明,他们并不像他们最初看起来那样可怕.
这些是主要步骤:
drawRect
或使用a 绘制路径CAShapeLayer
.你可以做任何事情,但作为一个例子,我选择了下面的形状.它可以是键盘上的弹出键.
回顾一下你的形状设计并将其分解成更简单的线条元素(用于直线),弧形(用于圆形和圆角)和曲线(用于其他任何东西).
以下是我们的示例设计:
我们将在左下角任意开始并按顺时针方向工作.我将使用图像中的网格来获取点的x和y值.我会在这里对所有内容进行硬编码,但当然你不会在一个真实的项目中做到这一点.
基本过程是:
UIBezierPath
moveToPoint
addLineToPoint
addArcWithCenter
addCurveToPoint
closePath
以下是在上图中制作路径的代码.
func createBezierPath() -> UIBezierPath {
// create a new path
let path = UIBezierPath()
// starting point for the path (bottom left)
path.move(to: CGPoint(x: 2, y: 26))
// *********************
// ***** Left side *****
// *********************
// segment 1: line
path.addLine(to: CGPoint(x: 2, y: 15))
// segment 2: curve
path.addCurve(to: CGPoint(x: 0, y: 12), // ending point
controlPoint1: CGPoint(x: 2, y: 14),
controlPoint2: CGPoint(x: 0, y: 14))
// segment 3: line
path.addLine(to: CGPoint(x: 0, y: 2))
// *********************
// ****** Top side *****
// *********************
// segment 4: arc
path.addArc(withCenter: CGPoint(x: 2, y: 2), // center point of circle
radius: 2, // this will make it meet our path line
startAngle: CGFloat(M_PI), // ? radians = 180 degrees = straight left
endAngle: CGFloat(3*M_PI_2), // 3?/2 radians = 270 degrees = straight up
clockwise: true) // startAngle to endAngle goes in a clockwise direction
// segment 5: line
path.addLine(to: CGPoint(x: 8, y: 0))
// segment 6: arc
path.addArc(withCenter: CGPoint(x: 8, y: 2),
radius: 2,
startAngle: CGFloat(3*M_PI_2), // straight up
endAngle: CGFloat(0), // 0 radians = straight right
clockwise: true)
// *********************
// ***** Right side ****
// *********************
// segment 7: line
path.addLine(to: CGPoint(x: 10, y: 12))
// segment 8: curve
path.addCurve(to: CGPoint(x: 8, y: 15), // ending point
controlPoint1: CGPoint(x: 10, y: 14),
controlPoint2: CGPoint(x: 8, y: 14))
// segment 9: line
path.addLine(to: CGPoint(x: 8, y: 26))
// *********************
// **** Bottom side ****
// *********************
// segment 10: line
path.close() // draws the final line to close the path
return path
}
Run Code Online (Sandbox Code Playgroud)
注意:通过在单个命令中添加直线和圆弧可以减少上述代码中的一些(因为圆弧具有隐含的起点).有关详细信息,请参见此处
我们可以在一层或一层中绘制路径drawRect
.
方法1:在图层中绘制路径
我们的自定义类看起来像这样.CAShapeLayer
初始化视图时,我们将Bezier路径添加到新路径.
import UIKit
class MyCustomView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup() {
// Create a CAShapeLayer
let shapeLayer = CAShapeLayer()
// The Bezier path that we made needs to be converted to
// a CGPath before it can be used on a layer.
shapeLayer.path = createBezierPath().cgPath
// apply other properties related to the path
shapeLayer.strokeColor = UIColor.blue.cgColor
shapeLayer.fillColor = UIColor.white.cgColor
shapeLayer.lineWidth = 1.0
shapeLayer.position = CGPoint(x: 10, y: 10)
// add the new layer to our custom view
self.layer.addSublayer(shapeLayer)
}
func createBezierPath() -> UIBezierPath {
// see previous code for creating the Bezier path
}
}
Run Code Online (Sandbox Code Playgroud)
并在View Controller中创建我们的视图
override func viewDidLoad() {
super.viewDidLoad()
// create a new UIView and add it to the view controller
let myView = MyCustomView()
myView.frame = CGRect(x: 100, y: 100, width: 50, height: 50)
myView.backgroundColor = UIColor.yellow
view.addSubview(myView)
}
Run Code Online (Sandbox Code Playgroud)
我们得到......
嗯,这有点小,因为我硬编码所有的数字.我可以扩大路径大小,但是,像这样:
let path = createBezierPath()
let scale = CGAffineTransform(scaleX: 2, y: 2)
path.apply(scale)
shapeLayer.path = path.cgPath
Run Code Online (Sandbox Code Playgroud)
方法2:绘制路径 draw
使用draw
比绘制到图层要慢,因此如果您不需要,这不是推荐的方法.
以下是我们自定义视图的修订代码:
import UIKit
class MyCustomView: UIView {
override func draw(_ rect: CGRect) {
// create path (see previous code)
let path = createBezierPath()
// fill
let fillColor = UIColor.white
fillColor.setFill()
// stroke
path.lineWidth = 1.0
let strokeColor = UIColor.blue
strokeColor.setStroke()
// Move the path to a new location
path.apply(CGAffineTransform(translationX: 10, y: 10))
// fill and stroke the path (always do these last)
path.fill()
path.stroke()
}
func createBezierPath() -> UIBezierPath {
// see previous code for creating the Bezier path
}
}
Run Code Online (Sandbox Code Playgroud)
这给了我们相同的结果......
我真的建议看下面的材料.他们最终让Bézier的道路对我来说是可以理解的.(并告诉我如何发音:/bɛzi.eɪ/.)
Rui*_*res 53
如果您使用a会更容易CAShapeLayer
,如下所示:
CAShapeLayer *shapeView = [[CAShapeLayer alloc] init];
Run Code Online (Sandbox Code Playgroud)
并设置path
:
[shapeView setPath:[self createPath].CGPath];
Run Code Online (Sandbox Code Playgroud)
最后加上它:
[[self.view layer] addSublayer:shapeView];
Run Code Online (Sandbox Code Playgroud)
Fog*_*ter 15
您可以使用a CAShapeLayer
来执行此操作.
像这样...
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [self createPath].CGPath;
shapeLayer.strokeColor = [UIColor redColor].CGColor; //etc...
shapeLayer.lineWidth = 2.0; //etc...
shapeLayer.position = CGPointMake(100, 100); //etc...
[self.layer addSublayer:shapeLayer];
Run Code Online (Sandbox Code Playgroud)
然后,这将添加并绘制路径,而不必覆盖drawRect
.
有多种方法可以实现您的目标.我最常见的是:覆盖drawRect,将您的形状绘制到CAShapeLayer中,然后将其作为子图层添加到视图中,或将路径绘制到另一个上下文中,将其另存为图像,然后将其添加到您的视图.
所有这些都是合理的选择,哪一个最好取决于许多其他因素,例如你是否会不断添加形状,调用它的频率等等.
归档时间: |
|
查看次数: |
60594 次 |
最近记录: |