feat: 初始化 iOS 远程控制端项目

This commit is contained in:
2026-07-29 10:34:02 +08:00
parent 11173eb04c
commit 1e37aa64cc
20 changed files with 2610 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
import UIKit
import SwiftUI
/// UIKit 0.0~1.0
/// Android RemoteTouchView
/// - MotionEventDOWN=0 / UP=1 / MOVE=2 / CANCEL=3""
/// - >= 200ms >= 2% SWIPE
final class RemoteTouchView: UIView {
/// Android MotionEvent
enum MotionAction {
static let down: Int32 = 0
static let up: Int32 = 1
static let move: Int32 = 2
static let cancel: Int32 = 3
}
var onMotionEvent: ((Int32, Double, Double) -> Void)?
var onSwipe: ((Double, Double, Double, Double, Int64) -> Void)?
private var startX: Double = 0
private var startY: Double = 0
private var touchStartTime: TimeInterval = 0
override init(frame: CGRect) {
super.init(frame: frame)
isMultipleTouchEnabled = false
backgroundColor = .clear
}
required init?(coder: NSCoder) {
super.init(coder: coder)
isMultipleTouchEnabled = false
backgroundColor = .clear
}
private func relativePoint(of touch: UITouch) -> (Double, Double) {
let p = touch.location(in: self)
let w = max(bounds.width, 1)
let h = max(bounds.height, 1)
let relX = min(max(Double(p.x / w), 0), 1)
let relY = min(max(Double(p.y / h), 0), 1)
return (relX, relY)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let (x, y) = relativePoint(of: touch)
startX = x
startY = y
touchStartTime = Date().timeIntervalSince1970
onMotionEvent?(MotionAction.down, x, y)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let (x, y) = relativePoint(of: touch)
onMotionEvent?(MotionAction.move, x, y)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let (x, y) = relativePoint(of: touch)
onMotionEvent?(MotionAction.up, x, y)
let duration = Int64((Date().timeIntervalSince1970 - touchStartTime) * 1000)
let dx = abs(x - startX)
let dy = abs(y - startY)
// SWIPE Android
if !(duration < 200 && dx < 0.02 && dy < 0.02) {
onSwipe?(startX, startY, x, y, duration)
}
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let (x, y) = relativePoint(of: touch)
onMotionEvent?(MotionAction.cancel, x, y)
}
}
/// SwiftUI UIKit SwiftUI
struct TouchOverlay: UIViewRepresentable {
let onMotionEvent: (Int32, Double, Double) -> Void
let onSwipe: (Double, Double, Double, Double, Int64) -> Void
func makeUIView(context: Context) -> RemoteTouchView {
let view = RemoteTouchView()
view.onMotionEvent = onMotionEvent
view.onSwipe = onSwipe
return view
}
func updateUIView(_ uiView: RemoteTouchView, context: Context) {
uiView.onMotionEvent = onMotionEvent
uiView.onSwipe = onSwipe
}
}