स्विफ्ट का उपयोग करके आईओएस में बाएं से दाएं नियंत्रक कैसे देखें


83

मैं नई स्क्रीन पेश करने के लिए presentViewController का उपयोग कर रहा हूं

let dashboardWorkout = DashboardWorkoutViewController()
presentViewController(dashboardWorkout, animated: true, completion: nil)

यह नीचे से ऊपर तक नई स्क्रीन प्रस्तुत करता है, लेकिन मैं चाहता हूं कि इसे बिना उपयोग किए दाएं से बाएं पेश किया जाए UINavigationController

मैं स्टोरीबोर्ड के बजाय Xib का उपयोग कर रहा हूं इसलिए मैं ऐसा कैसे कर सकता हूं?


संक्षेप में, पूर्ण उत्तर: stackoverflow.com/a/48081504/294884
Fattie

जवाबों:


160

इससे कोई फर्क नहीं पड़ता कि यह है xibया storyboardआप उपयोग कर रहे हैं। आम तौर पर, जब आप व्यू कंट्रोलर को प्रेजेंटर्स में धकेलते हैं तो लेफ्ट ट्रांजेक्शन का अधिकार इस्तेमाल होता है UINavigiationController

अपडेट करें

जोड़ा गया समय समारोह kCAMediaTimingFunctionEaseInEaseOut

स्विफ्ट 4 कार्यान्वयन के साथ नमूना परियोजना गिथब में जोड़ा गया


स्विफ्ट 3 और 4.2

let transition = CATransition()
transition.duration = 0.5
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
transition.timingFunction = CAMediaTimingFunction(name:CAMediaTimingFunctionName.easeInEaseOut)
view.window!.layer.add(transition, forKey: kCATransition)
present(dashboardWorkout, animated: false, completion: nil)


ObjC

CATransition *transition = [[CATransition alloc] init];
transition.duration = 0.5;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[self.view.window.layer addAnimation:transition forKey:kCATransition];
[self presentViewController:dashboardWorkout animated:false completion:nil];


स्विफ्ट 2.x

let transition = CATransition()
transition.duration = 0.5
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)
view.window!.layer.addAnimation(transition, forKey: kCATransition)
presentViewController(dashboardWorkout, animated: false, completion: nil)

विधि के animatedपैरामीटर की तरह लगता है presentViewControllerवास्तव में कस्टम संक्रमण के इस मामले में कोई फर्क नहीं पड़ता। यह trueया तो किसी भी मूल्य का हो सकता है false


2
मैंने एक कस्टम UIStoryboardSegue के प्रदर्शन () विधि के भीतर Swift3 कोड का उपयोग करने की कोशिश की, समस्या यह है - संक्रमण एक ही दृश्य पर किया जाता है, और फिर, दूसरा दृश्य दिखाई देता है। उस बारे में कोई विचार?
देवर्षि

2
जब मैं इस पद्धति का उपयोग करता हूं, तो स्रोत वीसी बाहर फीका कर रहा है मैं कैसे उस फीका प्रभाव को हटा सकता हूं और उसके पास पुश एनीमेशन की तरह है?
उमर अफज़ल

1
@UmairAfzal खिड़की का रंग, आपको इससे बचने के लिए खिड़की का रंग बदलना होगा।
अब्दुल रहमान

इस संक्रमण का प्रभावी ढंग से उपयोग कैसे करें UIModalPresentationStyle.overCurrentContext के साथ Swift 3 में
ममता

3
यदि आप "एनिमेटेड" को "सच" करते हैं, तो इसमें थोड़ा ऊपर की तरफ एनीमेशन भी होगा। मैं इसे "झूठा" सेट करने की सलाह देता हूं
रेबेलपर

68

वर्तमान / बर्खास्तगी के लिए पूरा कोड, स्विफ्ट 3

extension UIViewController {

    func presentDetail(_ viewControllerToPresent: UIViewController) {
        let transition = CATransition()
        transition.duration = 0.25
        transition.type = kCATransitionPush
        transition.subtype = kCATransitionFromRight
        self.view.window!.layer.add(transition, forKey: kCATransition)

        present(viewControllerToPresent, animated: false)
    }

    func dismissDetail() {
        let transition = CATransition()
        transition.duration = 0.25
        transition.type = kCATransitionPush
        transition.subtype = kCATransitionFromLeft
        self.view.window!.layer.add(transition, forKey: kCATransition)

        dismiss(animated: false)
    }
}

2
कृपया और स्पष्ट बताएं। अधिक समझाएं !
एम्म

3
अपने उत्तर को अपवित्र करना क्योंकि इसमें खारिज करने का कार्य भी है
रेबेलपर

1
वहाँ सबसे अच्छा में से एक !! 👌
श्याम

44

सभी उत्तर पढ़ें और सही समाधान नहीं देख सकते हैं। ऐसा करने का सही तरीका यह है कि आप कस्टम वीसी डेलीगेट के लिए कस्टम UIViewControllerAnimatedTransitioning बनाएं।

तो यह और अधिक कदम बनाने के लिए मानता है, लेकिन परिणाम अधिक अनुकूलन योग्य है और कुछ साइड इफेक्ट नहीं है, जैसे प्रस्तुत दृश्य के साथ एक साथ देखने से बढ़ रहा है।

तो, मान लें कि आपके पास कुछ ViewController है, और प्रस्तुत करने के लिए एक विधि है

var presentTransition: UIViewControllerAnimatedTransitioning?
var dismissTransition: UIViewControllerAnimatedTransitioning?    

func showSettings(animated: Bool) {
    let vc = ... create new vc to present

    presentTransition = RightToLeftTransition()
    dismissTransition = LeftToRightTransition()

    vc.modalPresentationStyle = .custom
    vc.transitioningDelegate = self

    present(vc, animated: true, completion: { [weak self] in
        self?.presentTransition = nil
    })
}

presentTransitionऔर dismissTransitionआपके दृश्य नियंत्रकों को एनिमेट करने के लिए उपयोग किया जाता है। तो आप अपना ViewController UIViewControllerTransitioningDelegate:

extension ViewController: UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return presentTransition
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return dismissTransition
    }
}

इसलिए अंतिम चरण अपना कस्टम संक्रमण बनाना है:

class RightToLeftTransition: NSObject, UIViewControllerAnimatedTransitioning {
    let duration: TimeInterval = 0.25

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return duration
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let container = transitionContext.containerView
        let toView = transitionContext.view(forKey: .to)!

        container.addSubview(toView)
        toView.frame.origin = CGPoint(x: toView.frame.width, y: 0)

        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
            toView.frame.origin = CGPoint(x: 0, y: 0)
        }, completion: { _ in
            transitionContext.completeTransition(true)
        })
    }
}

class LeftToRightTransition: NSObject, UIViewControllerAnimatedTransitioning {
    let duration: TimeInterval = 0.25

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return duration
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let container = transitionContext.containerView
        let fromView = transitionContext.view(forKey: .from)!

        container.addSubview(fromView)
        fromView.frame.origin = .zero

        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseIn, animations: {
            fromView.frame.origin = CGPoint(x: fromView.frame.width, y: 0)
        }, completion: { _ in
            fromView.removeFromSuperview()
            transitionContext.completeTransition(true)
        })
    }
}

उस कोड में कंट्रोलर को वर्तमान संदर्भ में प्रस्तुत किया जाता है, आप उस बिंदु से अपने अनुकूलन कर सकते हैं। इसके अलावा आप देख सकते हैं कि कस्टम UIPresentationControllerउपयोगी है (उपयोग में पास UIViewControllerTransitioningDelegate)


बहुत बढ़िया! मैं थोड़ी देर के लिए सभी उत्तरों की कोशिश कर रहा था और कुछ सही नहीं था ... मैंने एक को भी उखाड़ दिया जो कि नहीं होना चाहिए था ...
रीमोंड हिल

जब आप प्रस्तुत कुलपति को खारिज करते हैं, तो क्या आप सिर्फ खारिज (एनिमेटेड: सच, पूरा: शून्य) कहते हैं ???
रीमोंड हिल

@ReimondHill हाँ, मैं सिर्फ साधारण बर्खास्तगी का उपयोग कर रहा हूँकंट्रोलर
HotJard

यह अब तक का सबसे अच्छा समाधान है। हां, यह थोड़ा अधिक जटिल है, लेकिन यह मजबूत है और विभिन्न परिस्थितियों में नहीं टूटेगा। स्वीकृत उत्तर हैक है।
mmh02

आईफोन 7+, 8+, एक्स, एक्समैक्स को छोड़कर सभी डिवाइस पर इसका पूरी तरह से काम कर रहा है। कोई विचार क्यों? vc पूरा फ्रेम नहीं ले रहा है।
उमर अफज़ल

14

आप कस्टम सेग का भी उपयोग कर सकते हैं।

स्विफ्ट 5

class SegueFromRight: UIStoryboardSegue {

    override func perform() {
        let src = self.source
        let dst = self.destination

        src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
        dst.view.transform = CGAffineTransform(translationX: src.view.frame.size.width, y: 0)

        UIView.animate(withDuration: 0.25,
               delay: 0.0,
               options: UIView.AnimationOptions.curveEaseInOut,
               animations: {
                    dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
            },
                   completion: { finished in
                    src.present(dst, animated: false, completion: nil)
        })
    }
}

बेहतर उत्तर तो अन्य अगर वर्तमान संदर्भ में प्रस्तुति में उपयोग किया जाता है
वरुण नाहरिया

इस कस्टम सेग को खारिज करते समय यह अभी भी मूल सेग प्रकार को डिफॉल्ट करता है। क्या इसके आसपास कोई रास्ता है?
एलेक्स बेली

1
जबकि कस्टम सेग महान हैं - वे केवल एक स्टोरीबोर्ड समाधान हैं
फेटी

7

इसे इस्तेमाल करे,

    let animation = CATransition()
    animation.duration = 0.5
    animation.type = kCATransitionPush
    animation.subtype = kCATransitionFromRight
     animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    vc.view.layer.addAnimation(animation, forKey: "SwitchToView")

    self.presentViewController(vc, animated: false, completion: nil)

यहाँ आपके मामले में vcviewcontroller है dashboardWorkout


3
धन्यवाद, लेकिन अगले कुलपति अचानक से बाएं से अपील करने के बजाय अचानक दिखाई दे रहे हैं। मैंने एनीमेशन अवधि को बदल दिया, लेकिन अभी भी वही है
उमैर अफजल

4

अगर आप "क्विक फिक्स" कैटरेन्शन विधि का उपयोग करना चाहते हैं ...।

class AA: UIViewController

 func goToBB {

    let bb = .. instantiateViewcontroller, storyboard etc .. as! AlreadyOnboardLogin

    let tr = CATransition()
    tr.duration = 0.25
    tr.type = kCATransitionMoveIn // use "MoveIn" here
    tr.subtype = kCATransitionFromRight
    view.window!.layer.add(tr, forKey: kCATransition)

    present(bb, animated: false)
    bb.delegate, etc = set any other needed values
}

और फिर ...

func dismissingBB() {

    let tr = CATransition()
    tr.duration = 0.25
    tr.type = kCATransitionReveal // use "Reveal" here
    tr.subtype = kCATransitionFromLeft
    view.window!.layer.add(tr, forKey: kCATransition)

    dismiss(self) .. or dismiss(bb), or whatever
}

यह सब दुर्भाग्य से सही नहीं है :(

CATransition वास्तव में यह काम करने के लिए नहीं बना है।

ध्यान दें कि आपको कष्टप्रद क्रॉस फीका पड़ जाएगा जो दुर्भाग्य से प्रभाव को बर्बाद कर देगा।


कई देवता (मेरे जैसे) वास्तव में उपयोग करना पसंद नहीं करते हैं NavigationController। अक्सर, यह विशेष रूप से असामान्य और जटिल ऐप्स के लिए, जैसे-जैसे आप जाते हैं, वैसे ही तदर्थ तरीके से पेश करना अधिक लचीला होता है। हालांकि, एक नौसेना नियंत्रक को "जोड़ना" मुश्किल नहीं है।

  1. बस स्टोरीबोर्ड पर, एंट्री वीसी पर जाएं और "नेवर कंट्रोलर में एम्बेड -> पर क्लिक करें।" वाकई ऐसा है। या,

  2. में didFinishLaunchingWithOptionsयह अगर आप चाहें तो अपने नव नियंत्रक बनाना आसान है,

  3. आपको वास्तव में चर को कहीं भी रखने की आवश्यकता नहीं है, क्योंकि .navigationControllerहमेशा एक संपत्ति के रूप में उपलब्ध है - आसान।

वास्तव में, एक बार जब आपके पास एक नेविगेशनकंट्रोलर होता है, तो यह स्क्रीन के बीच संक्रमण करने के लिए मामूली है,

    let nextScreen = instantiateViewController etc as! NextScreen
    navigationController?
        .pushViewController(nextScreen, animated: true)

और आप कर सकते हैं pop

हालांकि यह आपको केवल मानक सेब "दोहरी धक्का" प्रभाव देता है ...

(पुरानी एक कम गति पर बंद हो जाती है, जैसा कि नया एक स्लाइड पर होता है।)

आम तौर पर और आश्चर्यजनक रूप से, आपको आमतौर पर एक पूर्ण कस्टम संक्रमण करने के लिए प्रयास करना होगा।

यहां तक ​​कि अगर आप केवल सबसे सरल, सबसे आम, चाल-ओवर / चाल-बंद संक्रमण चाहते हैं, तो आपको एक पूर्ण कस्टम संक्रमण करना होगा।

सौभाग्य से, ऐसा करने के लिए इस क्यूए पर कुछ कट और पेस्ट बॉयलरप्लेट कोड है ... https://stackoverflow.com/a/48081504/294884 । नव वर्ष 2018 की हार्दिक शुभकामनाएँ!


3

UIKit आयात करें और UIViewController के लिए एक एक्सटेंशन बनाएं:

extension UIViewController {
func transitionVc(vc: UIViewController, duration: CFTimeInterval, type: CATransitionSubtype) {
    let customVcTransition = vc
    let transition = CATransition()
    transition.duration = duration
    transition.type = CATransitionType.push
    transition.subtype = type
    transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
    view.window!.layer.add(transition, forKey: kCATransition)
    present(customVcTransition, animated: false, completion: nil)
}}

simlpy कॉल के बाद:

let vC = YourViewController()
transitionVc(vc: vC, duration: 0.5, type: .fromRight)

बाएं से दाएं:

let vC = YourViewController()
transitionVc(vc: vC, duration: 0.5, type: .fromleft)

आप अपनी पसंदीदा अवधि के साथ अवधि बदल सकते हैं ...


1

इसे इस्तेमाल करे।

let transition: CATransition = CATransition()
transition.duration = 0.3

transition.type = kCATransitionReveal
transition.subtype = kCATransitionFromLeft
self.view.window!.layer.addAnimation(transition, forKey: nil)
self.dismissViewControllerAnimated(false, completion: nil)

1
let transition = CATransition()
    transition.duration = 0.25
    transition.type = kCATransitionPush
    transition.subtype = kCATransitionFromLeft
    transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    tabBarController?.view.layer.add(transition, forKey: kCATransition)
    self.navigationController?.popToRootViewController(animated: true)

मैंने इसे अपने बटन में एनीमेशन के लिए क्लिक की गई घटना में जोड़ा है। यह मेरे लिए Xcode 10.2 स्विफ्ट 4 में काम करता है
Chilli

0

वर्तमान में स्विफ्ट का उपयोग करते हुए आईओएस में बाएं से दाएं नियंत्रक

func FrkTransition() 

{
    let transition = CATransition()

    transition.duration = 2

    transition.type = kCATransitionPush

    transitioningLayer.add(transition,forKey: "transition")

    // Transition to "blue" state

    transitioningLayer.backgroundColor = UIColor.blue.cgColor
    transitioningLayer.string = "Blue"
}

Refrence द्वारा: [ https://developer.apple.com/documentation/quartzcore/catransitioniding [1 ]


-1

मेरे पास एक बेहतर समाधान है जिसने मेरे लिए काम किया है यदि आप ऐप्पल के क्लासिक एनीमेशन को मंत्रमुग्ध करना चाहते हैं, तो बिना उस "काले" संक्रमण को देखें जिसे आप कैट्रिशन () का उपयोग करते हुए देखते हैं। बस popToViewController विधि का उपयोग करें।

आप उस दृश्य को देख सकते हैं, जिसकी आपको आवश्यकता है

self.navigationController.viewControllers // Array of VC that contains all VC of current stack

आप पुनर्स्थापना के लिए खोजकर अपनी जरूरत के हिसाब से देख सकते हैं।

BE CAREFUL: उदाहरण के लिए, यदि आप 3 व्यू कंट्रोलर के माध्यम से नेविगेट कर रहे हैं, और आखिरी में आने पर आप पहले को पॉप करना चाहते हैं। आप खो देंगे, इस मामले में, प्रभावी सेकंड व्यू कंट्रोलर को देखें क्योंकि popToViewController ने इसे ओवरराइट कर दिया है। BTW, एक समाधान है: आप आसानी से popToViewcontroller से पहले बचा सकते हैं, वीसी आपको बाद में आवश्यकता होगी। इसने मेरे लिए बहुत अच्छा काम किया।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.