当前位置:网站首页>2- use line segments to form graphics and coordinate conversion
2- use line segments to form graphics and coordinate conversion
2022-06-23 08:24:00 【the Summer Palace】
This article uses a custom checkbox Example of a button , Show me how to use Core Graphics The multi line drawing function of the drawing control UI .
CheckButton
First create CheckButton class :
// 1
class CheckButton: ShadowButton {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
// 2
fileprivate func commonInit() {
text = nil
}
// 3
override public func selectDraw(_ frame: CGRect) {
// 4
super.selectDraw(frame)
// 5
let selectedColor = UIColor(red: 0, green: 249/255, blue: 192/255, alpha: 1)
LinePainter.drawCheckMark(selectedColor, targetFrame: frame, shadow: outerShadow)
}
// 6
override public func unselectDraw(_ frame: CGRect) {
super.unselectDraw(frame)
LinePainter.drawCheckMark(.white, targetFrame: frame, shadow: outerShadow)
}
}
extension CheckButton {
// 7
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
isSelected = !isSelected
setNeedsDisplay()
}
// 8
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {}
}
- CheckButton Inherited ShadowButton, Because it also wants to have ShadowButton The inner and outer shadows of 、 Fill the gradient of the background 、 Attributes such as fillet radius .
- commonInit In the method , We will text Property is empty , Because it doesn't need to display text .
- drawSelect Method , Draw function when selected .
- First , Call inherited drawSelect Method .
- And then call LinePainter Draw a green check mark for us to indicate the check .
- Cover unselectDraw Method . Draw unselected state , Follow selectDraw In the same way , The only difference is that the color of the tick is changed to white .
- touchBegan Method , Handle the touch of the button , For one checkbox Control , Let it in select/unselect Just switch between .
- touchEnded Method null implementation , Because we don't want to release the effect of state restoration after touch .
LinePainter
LinePainter It's the first time we met 3 individual Painter, It provides a method for drawing multi line segments , And how to draw a tick for us .
class LinePainter {
private let context: CGContext?
init() {
self.context = UIGraphicsGetCurrentContext()
}
// 1.
func polyLines(_ points: [CGPoint]) -> UIBezierPath {
let path = UIBezierPath()
for i in 0..<points.count {
if i == 0 {
path.move(to: points[0])
}else{
path.addLine(to: points[i])
}
}
return path
}
// 2
func drawCheckMark(_ color: UIColor, targetFrame: CGRect, shadow: NSShadow?) {
if let context = context {
// 3
let originFrame = CGRect(x: 75, y: 22, width: 96, height: 96)
let vertex1 = convert(CGPoint(x: 100, y: 78),originFrame: originFrame, newFrame: targetFrame)
let vertex2 = convert(CGPoint(x: 117, y: 92), originFrame: originFrame,newFrame: targetFrame)
let vertex3 = convert(CGPoint(x: 151, y: 48), originFrame: originFrame, newFrame: targetFrame)
// 4
let path = polyLines([vertex1, vertex2, vertex3])
context.saveGState()
// 5
if let shadow = shadow {
context.setShadow(offset: shadow.shadowOffset, blur: shadow.shadowBlurRadius, color: (shadow.shadowColor as! UIColor).cgColor)
}
// 6
color.setStroke()
// 7
path.lineWidth = 7
// 8
path.lineJoinStyle = .round
// 9
path.stroke()
context.restoreGState()
}
}
// 10
private func convert(_ point: CGPoint, originFrame: CGRect, newFrame: CGRect) -> CGPoint {
let x:CGFloat = (point.x - originFrame.minX)/originFrame.width*newFrame.width + newFrame.minX
let y:CGFloat = (point.y - originFrame.minY)/originFrame.height*newFrame.height + newFrame.minY
return CGPoint(x:x, y: y)
}
}
- polyLines Draw a polyline , The parameter is one CGPoint Array . The so-called multi line segment is actually a broken line connected by multiple points . So the drawing of multi line segment is essentially a vertex ( Endpoint ) The draw .polyLines The function returns a CGPath.
- Draw a tick by drawing multiple line segments .
- A tick consists of three vertices , We calculate these respectively 3 vertices . The calculation of each vertex is a call to convert Function .
- Pass three vertices into polyLines function , So we can calculate a two-dimensional figure ( Tick ).
- If there is a shadow , Add shadow when painting .
- Set the drawing path to color .
- Set the line width .
- Set vertex fillet .
- Drawing graphics .
- convert The function calculates vertex coordinates . The coordinates on the design drawing need to be converted to get the coordinates of the control itself . Take the example here , The coordinates of the first point 75,22 Is the coordinates taken from the canvas on the design drawing ( You can use it. sketch). It first needs to subtract the coordinates of the upper left corner of the control in the canvas , Then multiply by the scale of the button ( That is, the size of the control in the original drawing divided by the added to view Future actual size ), Plus the control is put into view after frame The origin coordinates of , To finally convert to the correct coordinates .
test
stay viewDidLoad in :
let button = CheckButton(frame: CGRect(x: 100, y: 200, width: 100, height: 100))
button.gradient = gradient()
button.outerShadow = outerShadow()
button.innerShadow = innerShadow()
button.buttonRadius = 11
button.backgroundColor = .white
button.layer.cornerRadius = 20
addSubview(button)

边栏推荐
- 实战监听Eureka client的缓存更新
- After reading five books, I summarized these theories of wealth freedom
- C print zoom
- Capturing packets to find repeated acks and a large number of TCP retransmissions in TCP sessions -- sack (selective acknowledgement) technology
- 力扣(LeetCode)173. 二叉搜索树迭代器(2022.06.22)
- How to migrate x86 architecture applications to arm architecture at low cost
- @What is the difference between controller and @restcontroller?
- Data assets are king, analyzing the relationship between enterprise digital transformation and data asset management
- “方脸老师”董宇辉再回应热度下降:把农产品直播做好让农民受益 考虑去支教
- 高通9x07两种启动模式
猜你喜欢

INT 104_ LEC 06

点云库pcl从入门到精通 第十章

Ad object of Active Directory

PHP file contains -ctf

【论文笔记】Catching Both Gray and Black Swans: Open-set Supervised Anomaly Detection*

Introduction to typescript and basic types of variable definitions

What are the PCB characteristics inspection items?

Multi-scale feature combination in target detection

Object.defineProperty() 和 数据代理

论文阅读【Quo Vadis, Action Recognition? A New Model and the Kinetics Dataset】
随机推荐
GTEST死亡测试
Imperva- method of finding regular match timeout
Copy image bitmap by C # memory method
After easynvr video is enabled, no video file is generated. How to solve this problem?
如何评价代码质量
建立一有序的顺序表,并实现下列操作: 1.把元素x插入表中并保持有序; 2.查找值为x的元素,若找到将其删除; 3.输出表中各元素的值。
Set interface and set sub implementation classes
Idea true permanent activation method and permanent activation code tutorial
INT 104_ LEC 06
Explanation on webrtc's stun/turn service in tsingsee green rhino video
MySQL brochure notes 5 InnoDB record storage structure
2-用线段构成图形、坐标转换
Focus! Ten minutes to master Newton convex optimization
Integers and operators in go data types (3)
C Advanced Learning -- extended method (this)
How to mine keywords and improve user experience before website construction?
Tencent cloud account related
Google common syntax
Go language basic conditional statement if
MySQL小册子笔记 5 InnoDB 记录存储结构