2016-06-22 3 views
11

Я использую этот код теперь закрутить бутылку на кнопку крана:Спин бутылка с UIGestureRecognizer

@IBAction func spinButton(sender: AnyObject) { 
     let rotateView = CABasicAnimation() 
     let randonAngle = arc4random_uniform(360) + 720 
     rotateView.fromValue = 0 
     rotateView.toValue = Float(randonAngle) * Float(M_PI)/180.0 
     rotateView.duration = 3 
     rotateView.delegate = self 
     rotateView.repeatCount = 0 
     rotateView.removedOnCompletion = false 
     rotateView.fillMode = kCAFillModeForwards 
     rotateView.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) 
     bottleImageView.layer.addAnimation(rotateView, forKey: "transform.rotation.z") 
    } 

Но как я могу повернуть кнопку с помощью жеста? Таким образом, чем быстрее/быстрее я двигаю пальцем, тем быстрее бутылка будет вращаться.

+1

Просто интересно, увидели ли вы мое редактирование на мой ответ. Теперь он включает в себя весь быстрый код, чтобы это можно было сделать. – Fogmeister

+0

Вы, кажется, позаботились об этом. Just6 проверяет, есть ли у вас работа? Спасибо – Fogmeister

ответ

2

Простой ответ на этот вопрос ... используйте UIScrollView.

От моего вопроса здесь ... Loop UIScrollView but continue decelerating

Переводя его Swift тривиальна, но здесь идет ...

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    //make the content size really big so that the targetOffset of the deceleration will never be met. 

    scrollView.contentSize = CGSize(width: CGRectGetWidth(scrollView.frame) * 100.0, height: CGRectGetHeight(scrollView.frame)) 
    //set the contentOffset of the scroll view to a point in the center of the contentSize. 
    scrollView.setContentOffset(CGPoint(CGRectGetWidth(scrollView.frame) * 50, 0), animated: false) 
} 

func rotateImageView() { 
    //Calculate the percentage of one "frame" that is the current offset. 

    // each percentage of a "frame" equates to a percentage of 2 PI Rads to rotate 
    let minOffset = CGRectGetWidth(scrollView.frame) * 50.0 
    let maxOffset = CGRectGetWidth(scrollView.frame) * 51.0 

    let offsetDiff = maxOffset - minOffset 

    let currentOffset = scrollView.contentOffset.x - minOffset 

    let percentage = currentOffset/offsetDiff 

    arrowView.transform = CGAffineTransformMakeRotation(M_PI * 2 * percentage) 
} 

func scrollViewDidScroll(scrollView: UIScrollView) { 
    //the scrollView moved so update the rotation of the image 
    rotateImageView() 
} 

func scrollViewDidEndDecelerating(scrollView: UIScrollView) { 
    //the scrollview stopped moving. 
    //set the content offset back to be in the middle 
    //but make sure to keep the percentage (used above) the same 
    //this ensures the arrow is pointing in the same direction as it ended decelerating 

    let diffOffset = scrollView.contentOffset.x 

    while diffOffset >= CGRectGetWidth(scrollView.frame) { 
     diffOffset = diffOffset - CGRectGetWidth(scrollView.frame) 
    } 

    scrollView.setContentOffset(CGPoint(x: CGRectGetWidth(scrollView.frame) * 50 + diffOffset, y: 0), animated:false) 
} 

В этом примере мой взгляд прядения является arrowView. scrollView и arrowView должны быть одновременно рассмотрены в представлении контроллера. scrollView не должен иметь ничего в этом.

N.B. Это делается в браузере, поэтому могут возникнуть проблемы с синтаксисом. Возможно, вам также придется отдать некоторые цифры CGFloat и т. Д.

Кроме того, возможность перевода с Objective-C необходима для любого разработчика iOS. Миллионы приложений написаны с использованием Objective-C. Синтаксис может немного отличаться, но все API-интерфейсы одинаковы.

Обучение тому, что должно делать каждый iOS-разработчик.

+0

У вас есть какой-нибудь образец кода или что-то еще о том, как я это сделал? –

+0

@RoduckNickes Образец кода в моем блоге может использоваться одинаково. Все, что вам нужно сделать, это преобразовать contentOffset.x в угол. Возможно, 0 = 0 и 200 = 2 * Pi вращение. Тогда 400 = 4 * Pi и т. Д. Таким образом, каждые 200 точек прокрутки равны полному вращению. – Fogmeister

+0

@RoduckNickes Я искал код, который я сделал для этого, но я не мог его найти. Сожалею. Я думаю, что это был просто эксперимент, над которым я работал. – Fogmeister

1

Использование UIPanGestureRecognizer. Создайте panGestureRecognizer и добавьте его в супервизор вашей бутылки и реализуйте его делегат. Он имеет такие переменные, как velocityInView, translationInView. Когда пользователь заканчивает панорамирование, используйте их для расчета угла, скорости и продолжительности вашего вращения.

+1

ОК, поэтому вы создаете свой распознаватель жестов (у которого UIScrollView есть бесплатно) вы создаете свои методы для захвата скорости (которую UIScrollView имеет бесплатно), вы обновляете поворот на основе представленного перевода (который UIScrollView имеет бесплатно со смещением содержимого), то как вы вычисляете торможение на основе скорости, с которой пользователь выпустил свой кран? UIScrollView делает это за вас. Все вычисления и тяжелая работа, которые вы описали здесь, выполняются UIScrollView. Все, что вам нужно сделать, это выполнить смещение и повернуть изображение. – Fogmeister

+1

@Fogmeister Сколько вы задаете свой 'contentSize'? 1 миллион? это звучит не так. – farzadshbfn

+1

Как я это делал, чтобы установить размер контента на что-то сколь угодно большое. Это должно было гарантировать, что просмотр прокрутки никогда не доходил до конца в одном прокрутке.Однако, когда прокрутка прокрутки больше не прокручивается, ее можно вернуть обратно в 0 (+ - смещение на основе угла), чтобы каждый раз, когда вращение останавливается, оно возвращается. Эффективно делает его прокручиваемым бесконечно. – Fogmeister

2

Мне удалось создать образец приложения, который имеет вид в центре, который вы можете вращать с помощью UIRotationGestureRecognizer, и скорость вращения будет зависеть от скорости вращения. Я использовал UIDynamics для этого:

class ViewController: UIViewController { 

@IBOutlet weak var sampleView: UIView! 

var animator: UIDynamicAnimator? 

override func viewDidLoad() { 
    super.viewDidLoad() 

    setupRotationGesture() 

} 

override func viewDidAppear(animated: Bool) { 

    animator = UIDynamicAnimator(referenceView: self.view) 

    let sampleViewBehavior = UIDynamicItemBehavior(items: [self.sampleView]) 
    sampleViewBehavior.allowsRotation = true // view can rotate 
    animator?.addBehavior(sampleViewBehavior) 

    let anchoredSuperViewBehavior = UIDynamicItemBehavior(items: [self.view]) 
    anchoredSuperViewBehavior.anchored = true 
    animator?.addBehavior(anchoredSuperViewBehavior) 

    // Attachment between the sample view and super view at center anchor point. 

    let attachment = UIAttachmentBehavior.pinAttachmentWithItem(self.sampleView, attachedToItem: self.view, attachmentAnchor: CGPointMake(self.view.center.x + 1, self.view.center.y + 1)) 
    animator?.addBehavior(attachment) 
} 


// MARK: - Rotation Gesture - 

func setupRotationGesture(){ 

    let rotationGesture = UIRotationGestureRecognizer(target: self, action: #selector(handleRotationGesture(_:))) 
    self.sampleView.addGestureRecognizer(rotationGesture) 
} 

func handleRotationGesture(gesture: UIRotationGestureRecognizer){ 

    if gesture.state == .Ended { 

     let push = UIPushBehavior(items: [self.sampleView], mode: .Instantaneous) 

     push.magnitude = abs(50.5 * gesture.velocity) 
     let transform = self.sampleView.transform 
     push.angle = atan2(transform.b, transform.a); 
     animator?.addBehavior(push) 
    } 

} 
} 

При запуске вы сможете вращать вид, основанный на скорости вращения жеста.

+1

Спасибо, но он только вращается вправо, и он не перемещается когда я двигаю пальцем. Я должен использовать два пальца, и он длится до тех пор, пока он не перестанет вращаться. Есть идеи? –

+1

Вы можете использовать угол поворота в повороте, чтобы он мог работать с обеих сторон. Если вы хотите использовать один палец, вы можете использовать жестов салфетки, и я думаю, что это легко. Чтобы слишком долго останавливаться, вы можете изменить значение величины 'UIPushBehavior' Я дал вам идею и как это сделать. Его просто нужны некоторые настройки с вашей стороны :) –

Смежные вопросы