2016-02-14 10 views
10

Per impostazione predefinita, se si trascina a destra dal bordo sinistro dello schermo, trascinerà il ViewController e lo rimuoverà dallo stack.Come posso implementare "trascina verso destra per eliminare" un controller di vista che si trova in uno stack di navigazione?

Desidero estendere questa funzionalità a tutto lo schermo. Quando l'utente trascina ovunque, vorrei che succedesse lo stesso.

so che posso realizzare un colpo gesto giusto e semplicemente chiamare self.navigationController?.popViewControllerAnimated(true)

Tuttavia, non v'è alcun movimento "trascinamento". Voglio che l'utente sia in grado di trascinare a destra il controller della vista come se fosse un oggetto, rivelando cosa c'è sotto. E, se viene trascinato oltre il 50%, chiudilo. (Check out Instagram per capire cosa intendo.)

+0

penso che questo sarebbe utile per voi https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIScreenEdgePanGestureRecognizer_class/index.html#//apple_ref/occ/cl/UIScreenEdgePanGestureRecognizer – ColdSteel

+0

Instagram ignora oltre il 33%? Ho appena provato, ma mi sembra al 50% di respingere la vista. – Blaszard

+0

@Blaszard appena aggiornato. – TIMEX

risposta

16

enter image description here

Fatto un progetto demo in Github
https://github.com/rishi420/SwipeRightToPopController

I Ho usato il protocollo UIViewControllerAnimatedTransitioning

Dal doc:

// Viene utilizzato per cento guidato transizioni interattivi, nonché per controllori container ...

Aggiunta una UIPanGestureRecognizer alla visualizzazione del controller. Questa è l'azione del gesto:

func handlePanGesture(panGesture: UIPanGestureRecognizer) { 

    let percent = max(panGesture.translationInView(view).x, 0)/view.frame.width 

    switch panGesture.state { 

    case .Began: 
     navigationController?.delegate = self 
     navigationController?.popViewControllerAnimated(true) 

    case .Changed: 
     percentDrivenInteractiveTransition.updateInteractiveTransition(percent) 

    case .Ended: 
     let velocity = panGesture.velocityInView(view).x 

     // Continue if drag more than 50% of screen width or velocity is higher than 1000 
     if percent > 0.5 || velocity > 1000 { 
      percentDrivenInteractiveTransition.finishInteractiveTransition() 
     } else { 
      percentDrivenInteractiveTransition.cancelInteractiveTransition() 
     } 

    case .Cancelled, .Failed: 
     percentDrivenInteractiveTransition.cancelInteractiveTransition() 

    default: 
     break 
    } 
} 

Procedura:

  1. calcolare la percentuale di trascinamento sulla vista
  2. .Begin: Specifica quale Segue eseguire e assegnare UINavigationController delegato.delegato sarà necessario per InteractiveTransitioning
  3. .Changed: UpdateInteractiveTransition con percentuale
  4. .Ended: Continua restante transizione se trascinamento 50% o più o superiore velocità altrimenti annullare
  5. .Cancelled, .Failed: annullare transizione


Riferimenti:

  1. UIPercentDrivenInteractiveTransition
  2. https://github.com/visnup/swipe-left
  3. https://github.com/robertmryan/ScreenEdgeGestureNavigationController
  4. https://github.com/groomsy/custom-navigation-animation-transition-demo
+0

C'è un modo per farlo senza dover ricreare la transizione pop di default, che conosci? –

+0

Il passo 2 'caso .Begin:' dove si specifica 'segue'. potrebbe essere qualsiasi seguito della vostra scelta. –

+0

Non è quello che intendevo. Nel tuo progetto di esempio, crei una classe 'SlideAnimatedTransitioning' che simula l'animazione di transizione predefinita, giusto? Mi stavo chiedendo se posso semplicemente usare l'animazione di default, piuttosto che doverlo imitare ... –

-1

È possibile utilizzare colpo gesto giusto per questo scopo:

override func viewDidLoad() { 
    super.viewDidLoad() 

    var swipeRight = UISwipeGestureRecognizer(target: self, action: "popViewController:") 
    swipeRight.direction = UISwipeGestureRecognizerDirection.Right 
    self.view.addGestureRecognizer(swipeRight) 
} 


func popViewController(gesture: UIGestureRecognizer) { 

    if let swipeGesture = gesture as? UISwipeGestureRecognizer { 
     switch swipeGesture.direction { 
      case UISwipeGestureRecognizerDirection.Right: 
       self.navigationController.popViewControllerAnimated(true) 
      default: 
       break 
     } 
    } 
} 
Problemi correlati