আমি কেবলমাত্র কোনও মডেলটিকে খারিজ করার জন্য ইন্টারেক্টিভভাবে টেনে আনার জন্য একটি টিউটোরিয়াল তৈরি করেছি।
http://www.thorntech.com/2016/02/ios-tutorial-close-modal-dragging/
আমি প্রথমে এই বিষয়টিকে বিভ্রান্তিকর বলে মনে করেছি, সুতরাং টিউটোরিয়ালটি এটি ধাপে ধাপে তৈরি করে।
আপনি যদি কেবল কোডটি নিজে চালাতে চান তবে এটি রেপো:
https://github.com/ThornTechPublic/InteractiveModal
এটিই আমি ব্যবহার করেছি:
নিয়ামক দেখুন
আপনি একটি কাস্টম দিয়ে বরখাস্ত অ্যানিমেশনটিকে ওভাররাইড করুন। যদি ব্যবহারকারী মোডালটি টানছেন তবে interactor
কিক্স ইন।
import UIKit
class ViewController: UIViewController {
let interactor = Interactor()
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let destinationViewController = segue.destinationViewController as? ModalViewController {
destinationViewController.transitioningDelegate = self
destinationViewController.interactor = interactor
}
}
}
extension ViewController: UIViewControllerTransitioningDelegate {
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return DismissAnimator()
}
func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return interactor.hasStarted ? interactor : nil
}
}
অ্যানিম্যাটর খারিজ করুন
আপনি একটি কাস্টম অ্যানিমেটার তৈরি করুন। এটি একটি কাস্টম অ্যানিমেশন যা আপনি কোনও UIViewControllerAnimatedTransitioning
প্রোটোকলের অভ্যন্তরে প্যাকেজ করেন ।
import UIKit
class DismissAnimator : NSObject {
}
extension DismissAnimator : UIViewControllerAnimatedTransitioning {
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 0.6
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
guard
let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey),
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey),
let containerView = transitionContext.containerView()
else {
return
}
containerView.insertSubview(toVC.view, belowSubview: fromVC.view)
let screenBounds = UIScreen.mainScreen().bounds
let bottomLeftCorner = CGPoint(x: 0, y: screenBounds.height)
let finalFrame = CGRect(origin: bottomLeftCorner, size: screenBounds.size)
UIView.animateWithDuration(
transitionDuration(transitionContext),
animations: {
fromVC.view.frame = finalFrame
},
completion: { _ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
}
)
}
}
ইন্টারেক্টর
আপনি সাবক্লাস করেছেন UIPercentDrivenInteractiveTransition
যাতে এটি আপনার রাষ্ট্রের মেশিন হিসাবে কাজ করতে পারে। যেহেতু ইন্টারেক্টর বস্তুটি উভয় ভিসি দ্বারা অ্যাক্সেস করা হয়েছে, প্যানিংয়ের অগ্রগতি ট্র্যাক রাখতে এটি ব্যবহার করুন।
import UIKit
class Interactor: UIPercentDrivenInteractiveTransition {
var hasStarted = false
var shouldFinish = false
}
মডেল ভিউ কন্ট্রোলার
এটি ইন্টারঅ্যাক্টর পদ্ধতি কলগুলিতে প্যান অঙ্গভঙ্গির অবস্থার মানচিত্র করে। translationInView()
y
মান নির্ধারণ করে ব্যবহারকারী একটি থ্রেশহোল্ড অতিক্রম কিনা। যখন প্যানের অঙ্গভঙ্গি হয় .Ended
, তখন ইন্টারেক্টর হয় শেষ করে দেয় বা বাতিল করে দেয়।
import UIKit
class ModalViewController: UIViewController {
var interactor:Interactor? = nil
@IBAction func close(sender: UIButton) {
dismissViewControllerAnimated(true, completion: nil)
}
@IBAction func handleGesture(sender: UIPanGestureRecognizer) {
let percentThreshold:CGFloat = 0.3
let translation = sender.translationInView(view)
let verticalMovement = translation.y / view.bounds.height
let downwardMovement = fmaxf(Float(verticalMovement), 0.0)
let downwardMovementPercent = fminf(downwardMovement, 1.0)
let progress = CGFloat(downwardMovementPercent)
guard let interactor = interactor else { return }
switch sender.state {
case .Began:
interactor.hasStarted = true
dismissViewControllerAnimated(true, completion: nil)
case .Changed:
interactor.shouldFinish = progress > percentThreshold
interactor.updateInteractiveTransition(progress)
case .Cancelled:
interactor.hasStarted = false
interactor.cancelInteractiveTransition()
case .Ended:
interactor.hasStarted = false
interactor.shouldFinish
? interactor.finishInteractiveTransition()
: interactor.cancelInteractiveTransition()
default:
break
}
}
}