1. Introduction
Do not do what fancy, how to use the system API to quickly achieve scratch-off.
2. The actual combat
Idea: through the mask to achieve the effect of scraping. The scraping process can be transformed into a drawing process.
2.1 Subclass UIPanGestureRecognizer
class SNXPanGestureRecognizer: UIPanGestureRecognizer {
var touchBeganLocation: CGPoint?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
touchBeganLocation = touches.first?.location(in: view)
}
}
Copy the code
Why subclass UIPanGestureRecognizer?
Because UIPanGestureRecognizer in recognition when there is a recognition distance, if from UIGestureRecognizer State. Began to record, would have lost a key point, cause it is not from his starting place.
2.2 Scratch-off view
Create a two-tier view:
coverView
On the bottom, you can use solid colors, or your favorite scratch-off cover image.imageView
In the upper. Because the back is covered with a transparent layer, you can’t see what’s inside, just like the scratch-off cover. When we draw the pattern, the part of the pattern will be shown and obscuredcoverView
It’s like it’s been blown out.
// Cover view
let coverView: UIView = UIView()
coverView.backgroundColor = UIColor.gray
coverView.frame = CGRect(x: 0, y: 0, width: 350, height: 235)
coverView.center = view.center
view.addSubview(coverView)
// First prize picture
let imageView: UIImageView = UIImageView()
imageView.frame = coverView.frame
imageView.image = UIImage(named: "prize")
imageView.contentMode = .scaleAspectFill
view.addSubview(imageView)
Copy the code
The code for the mask layer is also simple. Once the required parameters are configured, add a mask to the imageView.
// maskLayer is the VC instance variable and will be used later in the action callback
let maskLayer: CAShapeLayer = CAShapeLayer(a)/ / montmorillonite layer
maskLayer.frame = imageView.bounds
maskLayer.lineWidth = 8.0
maskLayer.lineCap = CAShapeLayerLineCap.round
maskLayer.lineJoin = CAShapeLayerLineJoin.round
maskLayer.strokeColor = UIColor.black.cgColor
maskLayer.fillColor = UIColor.clear.cgColor
imageView.layer.mask = maskLayer
Copy the code
We added the gesture to coverView.
ImageView doesn’t respond to gestures by default, so I added coverView here.
This is where you can add to your favorite view based on your personal preference.
/ / gestures
let panGes: SNXPanGestureRecognizer = SNXPanGestureRecognizer(target: self, action: #selector(panGesHandler(_:)))
coverView.addGestureRecognizer(panGes)
Copy the code
The response code is also simple.
UIGestureRecognizer. State. Began to mobile users start touch points, then the addLine (to) the coordinates of gesture recognition, is the part of users start up. Then call addLine(to:) repeatedly to complete the drawing. Finally, update the path to the maskLayer.
// Path is the VC instance variable
let path: UIBezierPath = UIBezierPath(a)@objc func panGesHandler(_ recognizer: SNXPanGestureRecognizer) {
switch recognizer.state {
case .began:
if let touchBeganLocation = recognizer.touchBeganLocation {
path.move(to: touchBeganLocation)
}
fallthrough
case .changed, .ended, .cancelled:
path.addLine(to: recognizer.location(in: recognizer.view))
default:
break
}
maskLayer.path = path.cgPath
}
Copy the code
2.3 Complete Code
class ViewController: UIViewController {
let maskLayer: CAShapeLayer = CAShapeLayer(a)let path: UIBezierPath = UIBezierPath(a)override func viewDidLoad(a) {
super.viewDidLoad()
// Cover view
let coverView: UIView = UIView()
coverView.backgroundColor = UIColor.gray
coverView.frame = CGRect(x: 0, y: 0, width: 350, height: 235)
coverView.center = view.center
view.addSubview(coverView)
// First prize picture
let imageView: UIImageView = UIImageView()
imageView.frame = coverView.frame
imageView.image = UIImage(named: "prize")
imageView.contentMode = .scaleAspectFill
view.addSubview(imageView)
/ / montmorillonite layer
maskLayer.frame = imageView.bounds
maskLayer.lineWidth = 8.0
maskLayer.lineCap = CAShapeLayerLineCap.round
maskLayer.lineJoin = CAShapeLayerLineJoin.round
maskLayer.strokeColor = UIColor.black.cgColor
maskLayer.fillColor = UIColor.clear.cgColor
imageView.layer.mask = maskLayer
/ / gestures
let panGes: SNXPanGestureRecognizer = SNXPanGestureRecognizer(target: self, action: #selector(panGesHandler(_:)))
coverView.addGestureRecognizer(panGes)
}
@objc func panGesHandler(_ recognizer: SNXPanGestureRecognizer) {
switch recognizer.state {
case .began:
if let touchBeganLocation = recognizer.touchBeganLocation {
path.move(to: touchBeganLocation)
}
fallthrough
case .changed, .ended, .cancelled:
path.addLine(to: recognizer.location(in: recognizer.view))
default:
break
}
maskLayer.path = path.cgPath
}
}
Copy the code
If you like this article, give me a thumbs up ~ ❤️