带有部分边框的 UIView 边框
UIView border with partial border
我有 UIView,我只需要绘制一个边框部分视图,如何使用 UIBezierPath
如果你想使用UIBezierPath
,你可以选择“愚蠢”的方式:
- 画满您的视图边框
- 通过在边框顶部绘制一个矩形,用视图的背景颜色“掩盖”您不希望边框存在的部分。
class MyView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
layer.cornerRadius = 3
backgroundColor = .white
layer.masksToBounds = true
}
override func draw(_ rect: CGRect) {
let borderPath = UIBezierPath(roundedRect: bounds, cornerRadius: 3)
borderPath.lineWidth = 7
UIColor.gray.setStroke()
borderPath.stroke()
let covering = UIBezierPath(rect: CGRect(x: 20, y: -10, width: self.bounds.width - 40, height: 20))
backgroundColor?.setFill()
covering.fill()
}
}
输出:
除此之外,我想不出一个简单的方法来做到这一点。
但是,如果您可以使用 CAShapeLayer
...
您应该将 CAShapeLayer
的 strokeEnd
and strokeStart
属性设置为视图层的子层。
示例:
class MyView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
layer.cornerRadius = 3
let border = CAShapeLayer()
// make sure this path coincides with the border of the view
border.path = UIBezierPath(roundedRect: bounds, cornerRadius: 3).cgPath
// you should tweak these numbers
border.strokeStart = 0.3
border.strokeEnd = 0.7
border.strokeColor = UIColor.gray.cgColor
border.lineWidth = 3
border.fillColor = nil
layer.addSublayer(border)
backgroundColor = .white
}
}
输出:
我做了完全相同的事情,但做了一次动画,以模仿 android 材料文本字段设计和 ios 应用程序中的行为这里是形状创建代码:
placeholderWidth 是顶部间隙的大小,leftInset 从框架左角插入
class FloatingTextfieldBorderShapeCreator {
var leftInset: CGFloat
init(leftInset: CGFloat) {
self.leftInset = leftInset
}
func create(frame: CGRect, placeholderWidth: CGFloat) -> CGPath {
let path = UIBezierPath()
let arcRadius: CGFloat = 4.0
//1. starting point top left
let startingPoint = CGPoint(x: frame.minX + leftInset - 4, y: frame.minY)
path.move(to: startingPoint)
//2. top left arc
let topLeftArcCenter = CGPoint(x: frame.minX + arcRadius, y: arcRadius)
path.addArc(withCenter: topLeftArcCenter, radius: arcRadius, startAngle: 3*CGFloat.pi/2, endAngle: CGFloat.pi, clockwise: false)
//3. left line
let leftLineEndPoint = CGPoint(x: frame.minX, y: frame.height - arcRadius)
path.addLine(to: leftLineEndPoint)
//4. bottom left arc
let bottomLeftArcCenter = CGPoint(x: frame.minX + arcRadius, y: frame.height - arcRadius)
path.addArc(withCenter: bottomLeftArcCenter, radius: arcRadius, startAngle: CGFloat.pi, endAngle: CGFloat.pi/2, clockwise: false)
//5. bottom line
let bottomLineEndPoint = CGPoint(x: frame.width - arcRadius, y: frame.height)
path.addLine(to: bottomLineEndPoint)
//6. bottom right arc
let bottomRightArcCenter = CGPoint(x: frame.width - arcRadius, y: frame.height - arcRadius)
path.addArc(withCenter: bottomRightArcCenter, radius: arcRadius, startAngle: CGFloat.pi/2, endAngle: 0, clockwise: false)
//7. right line
let rightLineEndPoint = CGPoint(x: frame.width, y: frame.minY + arcRadius)
path.addLine(to: rightLineEndPoint)
//8. top right arc
let topRightArcCenter = CGPoint(x: frame.width - arcRadius, y: frame.minY + arcRadius)
path.addArc(withCenter: topRightArcCenter, radius: arcRadius, startAngle: 0, endAngle: -CGFloat.pi/2, clockwise: false)
//9. top line
let topLineEndPointX = startingPoint.x + placeholderWidth
let topLineEndPoint = CGPoint(x: topLineEndPointX, y: frame.minY)
path.addLine(to: topLineEndPoint)
return path.cgPath
}
}
要应用于绘图层的属性:
borderLayer.frame = borderFrame
borderLayer.fillColor = nil
borderLayer.lineWidth = 1.0
borderLayer.strokeColor = .lightGray
我有 UIView,我只需要绘制一个边框部分视图,如何使用 UIBezierPath
如果你想使用UIBezierPath
,你可以选择“愚蠢”的方式:
- 画满您的视图边框
- 通过在边框顶部绘制一个矩形,用视图的背景颜色“掩盖”您不希望边框存在的部分。
class MyView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
layer.cornerRadius = 3
backgroundColor = .white
layer.masksToBounds = true
}
override func draw(_ rect: CGRect) {
let borderPath = UIBezierPath(roundedRect: bounds, cornerRadius: 3)
borderPath.lineWidth = 7
UIColor.gray.setStroke()
borderPath.stroke()
let covering = UIBezierPath(rect: CGRect(x: 20, y: -10, width: self.bounds.width - 40, height: 20))
backgroundColor?.setFill()
covering.fill()
}
}
输出:
除此之外,我想不出一个简单的方法来做到这一点。
但是,如果您可以使用 CAShapeLayer
...
您应该将 CAShapeLayer
的 strokeEnd
and strokeStart
属性设置为视图层的子层。
示例:
class MyView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
layer.cornerRadius = 3
let border = CAShapeLayer()
// make sure this path coincides with the border of the view
border.path = UIBezierPath(roundedRect: bounds, cornerRadius: 3).cgPath
// you should tweak these numbers
border.strokeStart = 0.3
border.strokeEnd = 0.7
border.strokeColor = UIColor.gray.cgColor
border.lineWidth = 3
border.fillColor = nil
layer.addSublayer(border)
backgroundColor = .white
}
}
输出:
我做了完全相同的事情,但做了一次动画,以模仿 android 材料文本字段设计和 ios 应用程序中的行为这里是形状创建代码:
placeholderWidth 是顶部间隙的大小,leftInset 从框架左角插入
class FloatingTextfieldBorderShapeCreator {
var leftInset: CGFloat
init(leftInset: CGFloat) {
self.leftInset = leftInset
}
func create(frame: CGRect, placeholderWidth: CGFloat) -> CGPath {
let path = UIBezierPath()
let arcRadius: CGFloat = 4.0
//1. starting point top left
let startingPoint = CGPoint(x: frame.minX + leftInset - 4, y: frame.minY)
path.move(to: startingPoint)
//2. top left arc
let topLeftArcCenter = CGPoint(x: frame.minX + arcRadius, y: arcRadius)
path.addArc(withCenter: topLeftArcCenter, radius: arcRadius, startAngle: 3*CGFloat.pi/2, endAngle: CGFloat.pi, clockwise: false)
//3. left line
let leftLineEndPoint = CGPoint(x: frame.minX, y: frame.height - arcRadius)
path.addLine(to: leftLineEndPoint)
//4. bottom left arc
let bottomLeftArcCenter = CGPoint(x: frame.minX + arcRadius, y: frame.height - arcRadius)
path.addArc(withCenter: bottomLeftArcCenter, radius: arcRadius, startAngle: CGFloat.pi, endAngle: CGFloat.pi/2, clockwise: false)
//5. bottom line
let bottomLineEndPoint = CGPoint(x: frame.width - arcRadius, y: frame.height)
path.addLine(to: bottomLineEndPoint)
//6. bottom right arc
let bottomRightArcCenter = CGPoint(x: frame.width - arcRadius, y: frame.height - arcRadius)
path.addArc(withCenter: bottomRightArcCenter, radius: arcRadius, startAngle: CGFloat.pi/2, endAngle: 0, clockwise: false)
//7. right line
let rightLineEndPoint = CGPoint(x: frame.width, y: frame.minY + arcRadius)
path.addLine(to: rightLineEndPoint)
//8. top right arc
let topRightArcCenter = CGPoint(x: frame.width - arcRadius, y: frame.minY + arcRadius)
path.addArc(withCenter: topRightArcCenter, radius: arcRadius, startAngle: 0, endAngle: -CGFloat.pi/2, clockwise: false)
//9. top line
let topLineEndPointX = startingPoint.x + placeholderWidth
let topLineEndPoint = CGPoint(x: topLineEndPointX, y: frame.minY)
path.addLine(to: topLineEndPoint)
return path.cgPath
}
}
要应用于绘图层的属性:
borderLayer.frame = borderFrame
borderLayer.fillColor = nil
borderLayer.lineWidth = 1.0
borderLayer.strokeColor = .lightGray