よくある、指のドラッグに応じて「選択中」の四角いviewを画面に表示する方法。
指のドラッグに応じてシェイプを描く方法はこのSO記事、DashedUIView(UIViewのBorderを破線 dashed にする)についてはこちらのSO記事を参考にしました。
class ViewController: UIViewController {
var initialPoint: CGPoint = .zero
lazy var overlay: CustomDashedView = {
let view = CustomDashedView()
view.dashColor = .systemPink
view.dashWidth = 1
view.dashLength = 5
view.betweenDashesSpace = 2
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(overlay)
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(onViewSelected))
view.addGestureRecognizer(panGesture)
}
@objc func onViewSelected(_ sender: UIPanGestureRecognizer) {
let location = sender.location(in: view)
if sender.state == .began {
initialPoint = location
}
if sender.state == .changed {
// comparing the initialPoint and the current location, and get the smaller value for the x and y coordinate, set it as the origin of the rect
// abs() gives the absolute value
let rect = CGRect(x: min(initialPoint.x, location.x), y: min(initialPoint.y, location.y), width: abs(initialPoint.x - location.x), height: abs(initialPoint.y - location.y))
print(rect)
overlay.frame = rect
}
if sender.state == .ended {
overlay.frame.size = .zero
}
}
}
class CustomDashedView: UIView {
var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
var dashWidth: CGFloat = 0
var dashColor: UIColor = .clear
var dashLength: CGFloat = 0
var betweenDashesSpace: CGFloat = 0
var dashBorder: CAShapeLayer?
override func layoutSubviews() {
super.layoutSubviews()
dashBorder?.removeFromSuperlayer()
let dashBorder = CAShapeLayer()
dashBorder.lineWidth = dashWidth
dashBorder.strokeColor = dashColor.cgColor
dashBorder.lineDashPattern = [dashLength, betweenDashesSpace] as [NSNumber]
dashBorder.frame = bounds
dashBorder.fillColor = nil
if cornerRadius > 0 {
dashBorder.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
} else {
dashBorder.path = UIBezierPath(rect: bounds).cgPath
}
layer.addSublayer(dashBorder)
self.dashBorder = dashBorder
}
}