2016-03-12 9 views
6

Ho imparato Swift 2.2 per diversi giorni. Dopo aver terminato il tutorial ufficiale, sto cercando di fare alcuni esempi funzionali. Per esempio. Sto cercando di fare un decoratore di avatar.Swift: Come rendere l'inerzia uniforme dopo il panning (trascinamento)?

@IBAction func moveAvatar(recognizer:UIPanGestureRecognizer) { 
    recognizer.maximumNumberOfTouches = 1 
    recognizer.minimumNumberOfTouches = 1 
    let debugOutOfBounds = false 
    let debugGestureRecognizer = false 
    let debugVelocity = true 
    if (debugGestureRecognizer) { 
     print("pan") 
    } 
    let translation = recognizer.translationInView(self.avatar) 

    let standardAvatarSize:CGFloat = Conf.Size.avatarRadius * 2 
    if (self.avatar.frame.width < standardAvatarSize) { 
     self.avatar.frame = CGRect(origin: self.avatar.frame.origin, size: CGSize(width: standardAvatarSize, height:standardAvatarSize)) 
    } 
    if let view = recognizer.view { 
     switch recognizer.state { 
     case .Began: 
      if (debugVelocity) { 
       print("Began: velocity: \(recognizer.velocityInView(view)) translation: \(translation)") 
      } 

      self.panAvatarLastTranslation = translation 
      self.avatar.center = CGPoint(x: self.avatar.center.x + translation.x, y: self.avatar.center.y + translation.y) 
     case .Changed: 
      if (debugVelocity) { 
       print("Changed: velocity: \(recognizer.velocityInView(view)) translation: \(translation)") 
      } 
      if (translation != CGPoint(x: 0.0, y: 0.0)) { 
       self.panAvatarLastTranslation = translation 
      } 
      self.avatar.center = CGPoint(x: self.avatar.center.x + translation.x, y: self.avatar.center.y + translation.y) 
     case .Ended: 
      if (debugVelocity) { 
       print("Ended: velocity: \(recognizer.velocityInView(view)) translation: \(translation)") 
      } 
      let velocityDistance = sqrt(pow(recognizer.velocityInView(view).x, CGFloat(2)) + pow(recognizer.velocityInView(view).y, CGFloat(2))) 
      print(velocityDistance) 
      if (velocityDistance > 100) { 
       let inertiaDelay: NSTimeInterval = 0.5 
       let inertiaDistance : CGFloat = velocityDistance * CGFloat(inertiaDelay) * 0.02 
       let inertiaX:CGFloat = self.panAvatarLastTranslation.x * inertiaDistance 
       let inertiaY:CGFloat = self.panAvatarLastTranslation.y * inertiaDistance 
            //sqrt(pow(inertiaX, CGFloat(2)) + pow(inertiaY, CGFloat(2))) 
       //print("inertiaDelay: \(inertiaDelay)") 
       UIView.animateWithDuration(inertiaDelay, animations: { 
        self.avatar.center.x += inertiaX 
        self.avatar.center.y += inertiaY 
       }) 
      } 
     default: 
      print("default") 
     } 

     let standardAvatarBound: [String:CGFloat] = [ 
      "top": UIApplication.sharedApplication().statusBarFrame.height + UIScreen.mainScreen().bounds.width/2 - Conf.Size.avatarRadius, 
      "right": UIScreen.mainScreen().bounds.width/2 + Conf.Size.avatarRadius, 
      "bottom": UIApplication.sharedApplication().statusBarFrame.height + UIScreen.mainScreen().bounds.width/2 + Conf.Size.avatarRadius, 
      "left": UIScreen.mainScreen().bounds.width/2 - Conf.Size.avatarRadius 
     ] 
     let avatarBound: [String:CGFloat] = [ 
      "top": self.avatar.center.y - self.avatar.frame.height/2, 
      "right": self.avatar.frame.width/2 + self.avatar.center.x, 
      "bottom": self.avatar.center.y + self.avatar.frame.height/2, 
      "left": self.avatar.center.x - self.avatar.frame.width/2 
     ] 

     if (self.panAvatarLastTranslation.x < 0 && avatarBound["right"] < standardAvatarBound["right"]) { 
      UIView.animateWithDuration(0.5, animations: { 
       self.avatar.center.x += (standardAvatarBound["right"]! - avatarBound["right"]!) 
      }) 
      if (debugOutOfBounds) { 
       print("Out of right bound") 
      } 
     } 

     if(self.panAvatarLastTranslation.x > 0 && avatarBound["left"] > standardAvatarBound["left"]) { 
      UIView.animateWithDuration(0.5, animations: { 
       self.avatar.center.x -= (avatarBound["left"]! - standardAvatarBound["left"]!) 
      }) 
      if (debugOutOfBounds) { 
       print("Out of left bound") 
      } 
     } 

     if(self.panAvatarLastTranslation.y > 0 && avatarBound["top"] > standardAvatarBound["top"]) { 
      UIView.animateWithDuration(0.5, animations: { 
       self.avatar.center.y -= (avatarBound["top"]! - standardAvatarBound["top"]!) 
      }) 
      if (debugOutOfBounds) { 
       print("Out of top bound") 
      } 
     } 
     if(self.panAvatarLastTranslation.y < 0 && avatarBound["bottom"] < standardAvatarBound["bottom"]) { 
      UIView.animateWithDuration(0.5, animations: { 
       self.avatar.center.y += (standardAvatarBound["bottom"]! - avatarBound["bottom"]!) 
      }) 
      if (debugOutOfBounds) { 
       print("Out of bottom bound") 
      } 
     } 
    } 
    recognizer.setTranslation(CGPointZero, inView: view) 
} 

Va bene, come si può vedere che sto movimentazione trascinando l'inerzia nello stato ".Ended" del riconoscitore gesto padella. Funziona bene, ma non è scorrevole. Cosa posso fare per ottenere un'inerzia di panning uniforme?

Ecco il codice sorgente: https://github.com/AarioAi/NotesOpen/tree/master/Swift

risposta

1

Prova con metodo diverso per l'animazione. Heck out this tutorial

Problemi correlati