gpt4 book ai didi

ios - 在另一个圆形 UIView 中移动一个圆形 UIView

转载 作者:行者123 更新时间:2023-11-28 23:21:32 24 4
gpt4 key购买 nike

我正在尝试快速操纵操纵杆,我快完成了。

但我有一个问题,当我将操纵杆移动到“中间”时,操纵杆的移动很顺畅,但是当操纵杆接触到“它的容器”的边缘时,它变得迟钝。

但我知道为什么,因为我只允许摇杆在不触及边缘的情况下移动,我不知道如何纠正这个问题(在 else 中放入什么代码)。

这是我的代码和 GIF,以便您看得更清楚。

import UIKit
import SnapKit

class ViewController: UIViewController {

let joystickSize = 150
let substractSize = 200
let joystickOffset = 10

let joystickSubstractView = UIView()
let joystickView = UIView()

override func viewDidLoad() {
super.viewDidLoad()

joystickSubstractView.backgroundColor = .gray
joystickSubstractView.layer.cornerRadius = CGFloat(substractSize / 2)
self.view.addSubview(joystickSubstractView)

let panGesture = UIPanGestureRecognizer(target: self, action: #selector(dragJoystick))
joystickView.isUserInteractionEnabled = true
joystickView.addGestureRecognizer(panGesture)
joystickView.backgroundColor = .white
joystickView.layer.cornerRadius = CGFloat(joystickSize / 2)
joystickSubstractView.addSubview(joystickView)

joystickSubstractView.snp.makeConstraints {
$0.width.height.equalTo(substractSize)
$0.centerX.equalToSuperview()
$0.bottom.equalToSuperview().inset(150)
}

joystickView.snp.makeConstraints {
$0.width.height.equalTo(joystickSize)
$0.center.equalToSuperview()
}
}

@objc func dragJoystick(_ sender: UIPanGestureRecognizer) {
self.view.bringSubviewToFront(joystickView)
let translation = sender.translation(in: self.view)

let joystickCenter = joystickView.convert(joystickView.center, to: self.view)
let futureJoystickCenter = CGPoint(x: joystickCenter.x - joystickView.frame.minX + translation.x,
y: joystickCenter.y - joystickView.frame.minY + translation.y)
let distanceBetweenCenters = hypot(futureJoystickCenter.x - joystickSubstractView.center.x,
futureJoystickCenter.y - joystickSubstractView.center.y)

if CGFloat(substractSize / 2 + joystickOffset) >= (distanceBetweenCenters + CGFloat(joystickSize / 2)) {
joystickView.center = CGPoint(x: joystickView.center.x + translation.x,
y: joystickView.center.y + translation.y)
} else {
// I don't know what to put here to make the joystick "smoother"
}

sender.setTranslation(CGPoint.zero, in: self.view)
}
}

GIF

谢谢你的帮助

最佳答案

这是一种方法...

  • 计算外圆圆心到内圆圆心的最大可用距离,作为半径
  • 跟踪触摸/平移手势相对于外圆中心的位置
  • 如果从内圆(触摸点)中心到外圆中心的新距离大于最大半径,则将内圆中心移动到触摸中心线的交点和半径圆的边缘

这是它的外观,“操纵杆” View 的中心用绿点标识,半径圆显示为红色轮廓:

enter image description here

您可以尝试使用以下代码:

class JoyStickViewController: UIViewController {

let joystickSize: CGFloat = 150
let substractSize: CGFloat = 200

var innerRadius: CGFloat = 0.0

let joystickSubstractView = UIView()
let joystickView = UIView()

override func viewDidLoad() {
super.viewDidLoad()

joystickSubstractView.backgroundColor = .gray
joystickSubstractView.layer.cornerRadius = CGFloat(substractSize / 2)
self.view.addSubview(joystickSubstractView)

let panGesture = UIPanGestureRecognizer(target: self, action: #selector(dragJoystick(_:)))
joystickView.isUserInteractionEnabled = true
joystickView.addGestureRecognizer(panGesture)
joystickView.backgroundColor = .yellow
joystickView.layer.cornerRadius = CGFloat(joystickSize / 2)
joystickSubstractView.addSubview(joystickView)

joystickSubstractView.snp.makeConstraints {
$0.width.height.equalTo(substractSize)
$0.centerX.equalToSuperview()
$0.bottom.equalToSuperview().inset(150)
}

joystickView.snp.makeConstraints {
$0.width.height.equalTo(joystickSize)
$0.center.equalToSuperview()
}

// if you want the "joystick" circle to overlap the "outer circle" a bit, adjust this value
innerRadius = (substractSize - joystickSize) * 0.5


// start debugging / clarification...
// add a center "dot" to the joystick view
// add a red circle showing the inner radius - where we want to restrict the center of the joystick view
let jsCenterView = UIView()
jsCenterView.backgroundColor = .green
jsCenterView.layer.cornerRadius = 2.0
joystickView.addSubview(jsCenterView)
jsCenterView.snp.makeConstraints {
$0.width.height.equalTo(4.0)
$0.center.equalToSuperview()
}

let v = UIView()
v.backgroundColor = .clear
v.layer.borderColor = UIColor.red.cgColor
v.layer.borderWidth = 2
v.layer.cornerRadius = innerRadius
v.isUserInteractionEnabled = false
joystickSubstractView.addSubview(v)
v.snp.makeConstraints {
$0.width.height.equalTo(innerRadius * 2.0)
$0.center.equalToSuperview()
}

// end debugging / clarification

}

func lineLength(from pt1: CGPoint, to pt2: CGPoint) -> CGFloat {
return hypot(pt2.x - pt1.x, pt2.y - pt1.y)
}

func pointOnLine(from startPt: CGPoint, to endPt: CGPoint, distance: CGFloat) -> CGPoint {
let totalDistance = lineLength(from: startPt, to: endPt)
let totalDelta = CGPoint(x: endPt.x - startPt.x, y: endPt.y - startPt.y)
let pct = distance / totalDistance;
let delta = CGPoint(x: totalDelta.x * pct, y: totalDelta.y * pct)
return CGPoint(x: startPt.x + delta.x, y: startPt.y + delta.y)
}

@objc func dragJoystick(_ sender: UIPanGestureRecognizer) {

let touchLocation = sender.location(in: joystickSubstractView)

let outerCircleViewCenter = CGPoint(x: joystickSubstractView.bounds.width * 0.5, y: joystickSubstractView.bounds.height * 0.5)

var newCenter = touchLocation

let distance = lineLength(from: touchLocation, to: outerCircleViewCenter)

// if the touch would put the "joystick circle" outside the "outer circle"
// find the point on the line from center to touch, at innerRadius distance
if distance > innerRadius {
newCenter = pointOnLine(from: outerCircleViewCenter, to: touchLocation, distance: innerRadius)
}

joystickView.center = newCenter

}

}

注意:您可以删除(或注释掉)viewDidLoad()//start debugging//结束调试 注释删除绿色中心点和红色圆圈。

关于ios - 在另一个圆形 UIView 中移动一个圆形 UIView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59616783/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com