私は、stackoverflowの他のポストに触発され、少なくともスピンしている運命のホイールを実装しています。現在、私の問題は、画像の右端を下方向にスワイプすると、ホイールが間違った方向に回転することです。運命のホイールを実装する
誰かが間違っているのを見ることができますか?
class WOFView: UIView {
@IBOutlet weak var wheelImage: UIImageView!
private var history = [Dictionary<String, Any>]()
private var rotation: CGFloat = 0
private var startAngle: CGFloat = 0
private var circleRotationOffset: CGFloat = 0
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if let touchPoint = touches.first?.location(in: self){
startAngle = atan2(self.frame.width - touchPoint.y, self.frame.height - touchPoint.x)
rotation = startAngle
history.removeAll()
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
guard let touchPoint = touches.first?.location(in: self) else {
return
}
let dic = ["time" : NSNumber(value: CFAbsoluteTimeGetCurrent()),
"point": NSValue(cgPoint: touchPoint),
"rotation": NSNumber(value: Float(circleRotationOffset + rotation))]
history.insert(dic, at: 0)
if history.count == 3{
history.removeLast()
}
rotation = atan2(self.frame.width - touchPoint.y, self.frame.height - touchPoint.x) - startAngle
wheelImage.transform = CGAffineTransform(rotationAngle: circleRotationOffset + rotation)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
guard let touchPoint = touches.first?.location(in: self) else {
return
}
guard let lastObject = history.last else{
return
}
guard let pointValue = lastObject["point"] as? CGPoint else{
return
}
guard let timeValue = lastObject["time"] as? NSNumber else {
return
}
guard let rotationValue = lastObject["rotation"] as? NSNumber else {
return
}
let timeDif = CFAbsoluteTimeGetCurrent() - (timeValue.doubleValue)
circleRotationOffset = circleRotationOffset + rotation
let lastRotation = rotationValue.floatValue
let dist = sqrt(((pointValue.x - touchPoint.x) * (pointValue.x - touchPoint.x)) +
((pointValue.y - touchPoint.y) * (pointValue.y - touchPoint.y)))
let strength = max(Double(min(1.0, dist/80.0)) * (timeDif/0.25) * M_PI * 2, 0.3) * 30
print("S: \(strength)")
let p = circleRotationOffset
let dif = circleRotationOffset - CGFloat(lastRotation)
var inc = dif > 0
if dif > 3 || dif < -3{
inc = !inc
}
if (inc){
circleRotationOffset += CGFloat(strength)
}else{
circleRotationOffset -= CGFloat(strength)
}
let anim = CAKeyframeAnimation(keyPath: "transform.rotation.z")
anim.duration = max(strength/2, 1.0)
anim.isCumulative = true
anim.values = [NSNumber(value: Float(p)), Float(circleRotationOffset)]
anim.keyTimes = [NSNumber(value: Float(0)),NSNumber(value: Float(1.0))]
anim.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)]
anim.isRemovedOnCompletion = false
anim.fillMode = kCAFillModeForwards
wheelImage.layer.removeAllAnimations()
wheelImage.layer.add(anim, forKey: "rotate")
}
}
EDIT 私はUIPanGestureRecognizerで物事を単純化し、結果を共有したい:
enum SpinningDirection{
case clockwise
case antiClockwise
}
enum MajorDirection{
case up
case down
case left
case right
}
enum Quadrant{
case ul
case ur
case ll
case lr
}
class WOFView: UIView, CAAnimationDelegate {
@IBOutlet weak var wheelImage: UIImageView!
private var maxSpeed = 0
private var majorDirection = MajorDirection.right
private var quadrant = Quadrant.ul
private var spinningDirection = SpinningDirection.clockwise
private var winner = ""
func setup(){
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.respondToPanGesture))
addGestureRecognizer(panGesture)
}
func respondToPanGesture(gesture: UIPanGestureRecognizer){
let velocity = gesture.velocity(in: self)
let vX = abs(velocity.x)
let vY = abs(velocity.y)
let speed = Int(vX + vY)
if speed > maxSpeed{
maxSpeed = speed
}
let location = gesture.location(in: self)
if vX > vY{
majorDirection = (velocity.x > 0) ? .right : .left
}
else{
majorDirection = (velocity.y > 0) ? .down : .up
}
if location.x < self.frame.width/2 {
quadrant = (location.y < self.frame.height/2) ? .ul : .ll
}
else {
quadrant = (location.y < self.frame.height/2) ? .ur : .lr
}
switch quadrant {
case .ul:
switch majorDirection {
case .down, .left:
spinningDirection = .antiClockwise
case .up, .right:
spinningDirection = .clockwise
}
case .ur:
switch majorDirection {
case .down, .right:
spinningDirection = .clockwise
case .up, .left:
spinningDirection = .antiClockwise
}
case .lr:
switch majorDirection {
case .down, .left:
spinningDirection = .clockwise
case .up, .right:
spinningDirection = .antiClockwise
}
case .ll:
switch majorDirection {
case .down, .right:
spinningDirection = .antiClockwise
case .up, .left:
spinningDirection = .clockwise
}
}
if gesture.state == .began{
maxSpeed = 0
self.isUserInteractionEnabled = false
}
if gesture.state == .ended{
print("Ended")
print("MaxSpeed: \(maxSpeed)")
print("direction: \(spinningDirection)")
startAnimation(speed: maxSpeed, direction: spinningDirection)
}
}
private func startAnimation(speed: Int, direction : SpinningDirection){
var duration = Double(speed)/10
if duration > 10{
duration = 10
}
if duration < 3{
duration = 3
}
print("duration: \(duration)")
let multiplier = (direction == .clockwise) ? -1.0 : 1.0
let normalizedSpeed = Double(speed)/10 * multiplier
let goal = Double((speed * 100) % Int(2 * Double.pi * 100))/100.0
print("goal: \(goal)")
let halfPi = Double.pi/2
switch goal {
case 0*halfPi...1*halfPi:
winner = "1"
case 1*halfPi...2*halfPi:
winner = "4"
case 2*halfPi...3*halfPi:
winner = "3"
case 3*halfPi...4*halfPi:
winner = "2"
default:
print("?")
}
let anim = CAKeyframeAnimation(keyPath: "transform.rotation.z")
anim.duration = duration
anim.isCumulative = true
anim.values = [NSNumber(value: Float(normalizedSpeed)), Float(goal)]
anim.keyTimes = [NSNumber(value: Float(0)),NSNumber(value: Float(1))]
anim.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)]
anim.isRemovedOnCompletion = false
anim.fillMode = kCAFillModeForwards
anim.delegate = self
wheelImage.layer.removeAllAnimations()
wheelImage.layer.add(anim, forKey: "rotate")
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
print("The winner is \(winner)")
self.isUserInteractionEnabled = true
}
}
? – shallowThought
今はありません。どのようにこれを行うにはどのようなアイデア?私のイメージは円です。 – netshark1000