[iOS UI进阶 - 5.0] 手势解锁Demo
时间: 2023-06-28 07:05:01 浏览: 71
好的,这是一个手势解锁的Demo,你可以参考一下:
```
import UIKit
class GestureLockViewController: UIViewController {
// MARK: - Properties
var buttons = [UIButton]()
var selectedButtons = [UIButton]()
var lines = [CAShapeLayer]()
var touchPoint: CGPoint?
var isTouching = false
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let margin: CGFloat = 40
let distance: CGFloat = 80
let buttonWidth: CGFloat = 60
let buttonHeight: CGFloat = 60
let viewWidth = view.bounds.width
let viewHeight = view.bounds.height
for i in 0..<9 {
let row = CGFloat(i / 3)
let col = CGFloat(i % 3)
let x = margin + col * (buttonWidth + distance)
let y = margin + row * (buttonHeight + distance)
let button = UIButton(frame: CGRect(x: x, y: y, width: buttonWidth, height: buttonHeight))
button.layer.cornerRadius = buttonWidth / 2
button.layer.borderWidth = 2
button.layer.borderColor = UIColor.lightGray.cgColor
button.tag = i
view.addSubview(button)
buttons.append(button)
}
}
// MARK: - Gesture Methods
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let point = touch.location(in: view)
for button in buttons {
if button.frame.contains(point) && !selectedButtons.contains(button) {
touchPoint = button.center
selectedButtons.append(button)
isTouching = true
break
}
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard isTouching, let touch = touches.first else { return }
let point = touch.location(in: view)
touchPoint = point
for button in buttons {
if button.frame.contains(point) && !selectedButtons.contains(button) {
button.isSelected = true
selectedButtons.append(button)
let line = CAShapeLayer()
line.strokeColor = UIColor.gray.cgColor
line.fillColor = UIColor.clear.cgColor
line.lineWidth = 3
view.layer.addSublayer(line)
lines.append(line)
break
}
}
drawLines()
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
isTouching = false
touchPoint = nil
for button in buttons {
button.isSelected = false
}
validatePassword()
clearSelectedButtons()
clearLines()
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
isTouching = false
touchPoint = nil
for button in buttons {
button.isSelected = false
}
clearSelectedButtons()
clearLines()
}
// MARK: - Private Methods
private func drawLines() {
guard let point = touchPoint else { return }
let linePath = UIBezierPath()
linePath.move(to: point)
for button in selectedButtons {
linePath.addLine(to: button.center)
}
if let lastButton = selectedButtons.last, isTouching {
linePath.addLine(to: lastButton.convert(lastButton.center, to: view))
}
lines.last?.path = linePath.cgPath
}
private func clearSelectedButtons() {
for button in selectedButtons {
button.isSelected = false
}
selectedButtons.removeAll()
}
private func clearLines() {
for line in lines {
line.removeFromSuperlayer()
}
lines.removeAll()
}
private func validatePassword() {
let password = selectedButtons.map { "\($0.tag)" }.joined()
print("Gesture password: \(password)")
}
}
```
这个Demo实现了一个3x3的手势解锁界面,使用了`UIButton`和`CAShapeLayer`来实现。当用户滑动手指时,会根据手指位置,自动连接之前选中的按钮,形成一条线。当用户抬起手指时,会根据选中的按钮的顺序,输出一个密码。