নেভিগেশন ভিত্তিক অ্যাপে কীভাবে পুশ এবং পপ অ্যানিমেশনগুলি পরিবর্তন করতে হয়


221

আমার কাছে নেভিগেশন ভিত্তিক অ্যাপ্লিকেশন রয়েছে এবং আমি পুশ এবং পপ অ্যানিমেশনগুলির অ্যানিমেশন পরিবর্তন করতে চাই। আমি যে কিভাবে করতে হবে?

2018 সম্পাদনা করুন

এই প্রশ্নের অনেক উত্তর হয়েছে এবং এখন বেশ কিছুক্ষণ হয়ে গেছে, আমি এখন যেটিকে সবচেয়ে প্রাসঙ্গিক বলে মনে করি তার উত্তরটি পুনরায় নির্বাচন করেছি। যদি এমন কেউ থাকে যা অন্যথায় মনে করে দয়া করে আমাকে মন্তব্যে জানান


25
আইওএস 7 হিসাবে, এর জন্য অফিসিয়াল এপিআই রয়েছে; দেখতে UINavigationControllerDelegate এর কাস্টম রূপান্তরটি অ্যানিমেশন সমর্থন। এটি সম্পর্কে একটি ডাব্লুডাব্লুডিসি 2013 ভিডিও রয়েছে।
জেসি রুসাক

আমি সুইফটে এটি করার জন্য একটি উত্তর (নীচে) যুক্ত করেছি - আমি এই প্রশ্নটি সুইফট বাস্তবায়ন সম্পর্কে জিজ্ঞাসা করে এসেছিলাম তাই ভেবেছিলাম যে আমি আমার পরবর্তী বাস্তবায়নটি নিয়ে চিমিয়াম করব।
djbp

1
অফিসিয়াল (আইওএস 7+) এপিআইয়ের সাথে খুব ভাল টিউটোরিয়ালের জন্য দেখুন: bradbambara.wordpress.com/2014/04/11/…
নিকোলভস্কি

1
@ জেএসরুসাক ডাব্লুডাব্লুডিসি 2013 ভিডিওর আপডেট হওয়া লিঙ্ক: ভিডিও: বিকাশকারী.অ্যাপল.
ওয়াজিয়াচ রটকোভস্কি

1
আমার গৃহীত উত্তর বলছি n gals পরিবর্তন করা হয়েছে। আশাকরি এটা সাহায্য করবে! জিএলএইচএফ
জাব

উত্তর:


35

কোনও নেভিগেশন ভিত্তিক অ্যাপে কীভাবে পুশ এবং পপ অ্যানিমেশনগুলি পরিবর্তন করবেন ...

2019 এর জন্য, "চূড়ান্ত উত্তর!"

প্রস্তাবনা:

বলুন আপনি আইওএস বিকাশে নতুন are বিভ্রান্তিকরভাবে, অ্যাপল দুটি ট্রানজিশন সরবরাহ করে যা সহজেই ব্যবহার করা যায়। এগুলি হ'ল "ক্রসফেইড" এবং "ফ্লিপ"।

তবে অবশ্যই, "ক্রসফেইড" এবং "ফ্লিপ" অকেজো। তারা কখনও ব্যবহার করা হয় না। কেন অ্যাপল এই দুটি অকেজো ট্রানজিশন সরবরাহ করেছিল!

তাই:

বলুন যে আপনি একটি সাধারণ, সাধারণ, রূপান্তর যেমন "স্লাইড" করতে চান। সেক্ষেত্রে, আপনি কাজ একটি বিশাল পরিমাণ যা করতে হবে!

যে কাজ, এই পোস্টে ব্যাখ্যা করা হয়।

কেবল পুনরাবৃত্তি করতে:

আশ্চর্যের বিষয়: আইওএসের সাহায্যে, আপনি যদি সর্বাধিক সাধারণ, সর্বাধিক সাধারণ, দৈনন্দিন ট্রানজিশনগুলি (যেমন একটি সাধারণ স্লাইড) চান তবে আপনার একটি সম্পূর্ণ কাস্টম স্থানান্তর বাস্তবায়নের সমস্ত কাজ করতে হবে

এটি কীভাবে করবেন তা এখানে ...

1. আপনার একটি প্রথা দরকার UIViewControllerAnimatedTransitioning

  1. আপনার নিজের মতো একটি বুল দরকার popStyle। (এটি কি পপিং করছে, বা পপিং করছে?)

  2. আপনাকে অবশ্যই transitionDuration(তুচ্ছ) এবং মূল কলটি অন্তর্ভুক্ত করতে হবে ,animateTransition

  3. আসলে আপনাকে অবশ্যই অভ্যন্তরের জন্য দুটি ভিন্ন রুটিন লিখতে হবেanimateTransition । একটি ধাক্কা জন্য, এবং একটি পপ জন্য। সম্ভবত তাদের নাম দিন animatePushএবং animatePop। ভিতরে animateTransition, কেবল popStyleদুটি রুটিনে শাখা করুন

  4. নীচের উদাহরণটি একটি সরল মুভ-ওভার / মুভ-অফ করে

  5. আপনার animatePushএবং animatePopরুটিনগুলিতে আপনাকে অবশ্যই "ভিউ থেকে" এবং "দেখার জন্য" পেতে হবে। (এটি কীভাবে করবেন, কোড উদাহরণে প্রদর্শিত হবে))

  6. এবং আপনার অবশ্যই addSubview নতুন "থেকে" দেখার জন্য।

  7. এবং আপনাকে অবশ্যইcompleteTransition আপনার এনিমে শেষে কল করতে হবে

তাই ..

  class SimpleOver: NSObject, UIViewControllerAnimatedTransitioning {
        
        var popStyle: Bool = false
        
        func transitionDuration(
            using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
            return 0.20
        }
        
        func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
            
            if popStyle {
                
                animatePop(using: transitionContext)
                return
            }
            
            let fz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
            let tz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
            
            let f = transitionContext.finalFrame(for: tz)
            
            let fOff = f.offsetBy(dx: f.width, dy: 55)
            tz.view.frame = fOff
            
            transitionContext.containerView.insertSubview(tz.view, aboveSubview: fz.view)
            
            UIView.animate(
                withDuration: transitionDuration(using: transitionContext),
                animations: {
                    tz.view.frame = f
            }, completion: {_ in 
                    transitionContext.completeTransition(true)
            })
        }
        
        func animatePop(using transitionContext: UIViewControllerContextTransitioning) {
            
            let fz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
            let tz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
            
            let f = transitionContext.initialFrame(for: fz)
            let fOffPop = f.offsetBy(dx: f.width, dy: 55)
            
            transitionContext.containerView.insertSubview(tz.view, belowSubview: fz.view)
            
            UIView.animate(
                withDuration: transitionDuration(using: transitionContext),
                animations: {
                    fz.view.frame = fOffPop
            }, completion: {_ in 
                    transitionContext.completeTransition(true)
            })
        }
    }

এবং তারপর ...

২. এটি আপনার ভিউ কন্ট্রোলারে ব্যবহার করুন।

দ্রষ্টব্য: আশ্চর্যের বিষয় হল, আপনাকে কেবল "প্রথম" ভিউ কন্ট্রোলারে এটি করতে হবে। (যা "নীচে" রয়েছে))

আপনি যে শীর্ষে পপ করেন তার সাথে কিছুই করবেন না । সহজ।

সুতরাং আপনার ক্লাস ...

class SomeScreen: UIViewController {
}

হয়ে ...

class FrontScreen: UIViewController,
        UIViewControllerTransitioningDelegate, UINavigationControllerDelegate {
    
    let simpleOver = SimpleOver()
    

    override func viewDidLoad() {
        
        super.viewDidLoad()
        navigationController?.delegate = self
    }

    func navigationController(
        _ navigationController: UINavigationController,
        animationControllerFor operation: UINavigationControllerOperation,
        from fromVC: UIViewController,
        to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        
        simpleOver.popStyle = (operation == .pop)
        return simpleOver
    }
}

এটাই.

সাধারণ হিসাবে ধাক্কা এবং পপ করুন, কোনও পরিবর্তন নেই। ধাক্কা ...

let n = UIStoryboard(name: "nextScreenStoryboardName", bundle: nil)
          .instantiateViewController(withIdentifier: "nextScreenStoryboardID")
          as! NextScreen
navigationController?.pushViewController(n, animated: true)

এবং এটিকে পপ করতে আপনি যদি পছন্দ করেন তবে পরবর্তী পর্দায় এটি করতে পারেন:

class NextScreen: TotallyOrdinaryUIViewController {
    
    @IBAction func userClickedBackOrDismissOrSomethingLikeThat() {
        
        navigationController?.popViewController(animated: true)
    }
}

ইসস।


৩. এই পৃষ্ঠার অন্যান্য উত্তরগুলিও উপভোগ করুন যা কীভাবে অ্যানিমেটেড ট্রান্সশিশনকে ওভাররাইড করতে হয় তা ব্যাখ্যা করে

আজকাল AnimatedTransitioningআইওএস অ্যাপগুলিতে কীভাবে করা যায় সে সম্পর্কে আরও আলোচনার জন্য @ অ্যালানজিনো এবং @ এলিয়াসের উত্তরে স্ক্রোল করুন !


অসাধারণ! আমি যদি নেভিগেশন সোয়াইপ ব্যাক অঙ্গভঙ্গিটি একই অ্যানিমেটেড ট্রান্সশিশনিং সমর্থন করি। কোন ধারণা?
সাম চি ওয়েন

ধন্যবাদ @ সামচিউইন - সত্যিই এটি animatePushএবং হ'ল animatePopদুটি ভিন্ন দিক!
ফ্যাটি

268

আমি নিম্নলিখিতটি করেছিলাম এবং এটি দুর্দান্ত কাজ করে .. এবং এটি সহজ এবং সহজে বোঝা যায় ..

CATransition* transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
//transition.subtype = kCATransitionFromTop; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[[self navigationController] popViewControllerAnimated:NO];

এবং ধাক্কা জন্য একই জিনিস ..


সুইফট 3.0 সংস্করণ:

let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionFade
self.navigationController?.view.layer.add(transition, forKey: nil)
_ = self.navigationController?.popToRootViewController(animated: false)

34
+1, এটি সত্যিই সবচেয়ে বুদ্ধিমান সমাধান। ভবিষ্যতের দর্শকদের জন্য কেবল একটি ছোট্ট নোট: Animated:NOঅংশটি গুরুত্বপূর্ণ। যদি YESপাস হয়ে যায় তবে অ্যানিমেশনগুলি মিশে যায় এবং মজার প্রভাবের কারণ হয়।
ডার্কডাস্ট

12
এখন অবধি সেরা সমাধান .. এবং নতুনদের জন্য, কোয়ার্টকোর (# আইফোর্ট <কোয়ার্টজকোর / কোয়ার্টজোরিক h>) অন্তর্ভুক্ত করতে ভুলবেন না
Nomann

4
এই সমাধানটিতে আমার একমাত্র সমস্যা যা আমি অ্যানিমেশন ছাড়াই ধাক্কা দেওয়ার সাথে সাথে ধাক্কা করা ভিউকন্ট্রোলারের ভিউডিডঅ্যাপারটি কল হয়ে যায়। এর আশেপাশে কোন পথ আছে?
পেড্রো মাঞ্চো

9
এই কোডটি সহ আমার সমস্যাটি হ'ল বা বাইরে স্লাইড হওয়ার সাথে সাথে প্রতিটি দর্শন ধূসর বা সাদাতে ফ্ল্যাশ হয়।
ক্রিস

1
আইওএস 7.1.2 এবং আইওএস 8.3 এ যাচাই করা হয়েছে - এই setViewControllers:
কোডটিও

256

আমি এই কাজটি সর্বদা এভাবে পরিচালনা করতে সক্ষম হয়েছি।

পুশের জন্য:

MainView *nextView=[[MainView alloc] init];
[UIView  beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController:nextView animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
[nextView release];

পপ জন্য:

[UIView  beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
[UIView commitAnimations];

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelay:0.375];
[self.navigationController popViewControllerAnimated:NO];
[UIView commitAnimations];


আমি এখনও এ থেকে প্রচুর প্রতিক্রিয়া পেয়েছি তাই আমি এগিয়ে যেতে এবং এটি অ্যানিমেশন ব্লকগুলি ব্যবহার করতে আপডেট করব যা কোনওভাবেই অ্যানিমেশনগুলি করার অ্যাপল প্রস্তাবিত উপায়।

পুশের জন্য:

MainView *nextView = [[MainView alloc] init];
[UIView animateWithDuration:0.75
                         animations:^{
                             [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                             [self.navigationController pushViewController:nextView animated:NO];
                             [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
                         }];

পপ জন্য:

[UIView animateWithDuration:0.75
                         animations:^{
                             [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                             [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
                         }];
[self.navigationController popViewControllerAnimated:NO];

3
এর জন্য ধন্যবাদ. তবে পপটি ইউআইএনএভিগেশন কন্ট্রোলার দ্বারা স্বয়ংক্রিয়ভাবে সম্পন্ন হয়। আপনি কীভাবে সেই আচরণটিকে ওভাররাইড করবেন যাতে আপনি নিজের কাস্টম পপ লজিককে কল করতে পারেন?
জোশুয়া ফ্র্যাঙ্ক

1
@ স্টকজ আসলে কাজ করে !!! আপনি শুধু প্রতিস্থাপন আছে superদ্বারাself.navigationController
holierthanthou84

ডান থেকে ডিফল্ট স্লাইডের পরিবর্তে বাম দিক থেকে কোনও স্লাইড পাওয়ার কোনও উপায় আছে কি?
শিম

প্রথমটি নতুন দৃশ্যটি মোটেও দেখায় না। দ্বিতীয়টি অ্যানিমেশন দেখায় না। খুব খারাপ উত্তর! আইওএস 7.
দিমিত্রি

2
কেন আপনি "ভিউকন্ট্রোলার UIViewController" অংশটি ছাড়াই সাবক্লাসকে একটি নাম দিয়েছেন। এই নামটি ইউআইভিউ-র জন্য আরও উপযুক্ত।
ব্যবহারকারী 2159978

29

ধাক্কা জন্য

CATransition *transition = [CATransition animation];
transition.duration = 0.3;
transition.type = kCATransitionFade;
//transition.subtype = kCATransitionFromTop;

[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:ViewControllerYouWantToPush animated:NO];

পপ জন্য

CATransition *transition = [CATransition animation];
transition.duration = 0.3;
transition.type = kCATransitionFade;
//transition.subtype = kCATransitionFromTop;

[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];

19

@ ম্যাগনাস উত্তর, কেবলমাত্র সুইফ্টের জন্য (2.0)

    let transition = CATransition()
    transition.duration = 0.5
    transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.type = kCATransitionPush
    transition.subtype = kCATransitionFromTop
    self.navigationController!.view.layer.addAnimation(transition, forKey: nil)
    let writeView : WriteViewController = self.storyboard?.instantiateViewControllerWithIdentifier("WriteView") as! WriteViewController
    self.navigationController?.pushViewController(writeView, animated: false)

কিছু সাইডেনোটস:

আপনি সেগের সাথে এটিও করতে পারেন, কেবল এটিকে prepareForSegueবা এর মধ্যে প্রয়োগ করুন shouldPerformSegueWithIdentifierতবে এটি এটির মধ্যেও ডিফল্ট অ্যানিমেশনটি রাখবে। এটি ঠিক করতে আপনাকে স্টোরিবোর্ডে যেতে হবে, সেগুতে ক্লিক করুন এবং 'অ্যানিম্যাটস' বাক্সটি আনচেক করুন। তবে এটি আপনার অ্যাপ্লিকেশনটি আইওএস 9.0 এবং এর থেকে উপরে সীমাবদ্ধ করবে (আমি এক্সকোড 7 এ এটি কমপক্ষে করলেই হবে)।

কোনও বিভাগে করার সময়, শেষ দুটি লাইনটি প্রতিস্থাপন করা উচিত:

self.navigationController?.popViewControllerAnimated(false)

যদিও আমি মিথ্যা সেট করেছি, এটি এক ধরণের উপেক্ষা করে।


অ্যানিমেশন শেষে পটভূমিতে কালো রঙটি কীভাবে সরিয়ে ফেলা যায়।
মধু

পুশ ভিউ কন্ট্রোলার অ্যানিমেশনটির জন্য কাজ করা পপ ভিউ কন্ট্রোলারের জন্য কাজ করে
মুকুল মোর

16

মনে রাখবেন যে সুইফট , এক্সটেনশন স্পষ্টভাবে আপনার বন্ধু!

public extension UINavigationController {

    /**
     Pop current view controller to previous view controller.

     - parameter type:     transition animation type.
     - parameter duration: transition animation duration.
     */
    func pop(transitionType type: String = kCATransitionFade, duration: CFTimeInterval = 0.3) {
        self.addTransition(transitionType: type, duration: duration)
        self.popViewControllerAnimated(false)
    }

    /**
     Push a new view controller on the view controllers's stack.

     - parameter vc:       view controller to push.
     - parameter type:     transition animation type.
     - parameter duration: transition animation duration.
     */
    func push(viewController vc: UIViewController, transitionType type: String = kCATransitionFade, duration: CFTimeInterval = 0.3) {
        self.addTransition(transitionType: type, duration: duration)
        self.pushViewController(vc, animated: false)
    }

    private func addTransition(transitionType type: String = kCATransitionFade, duration: CFTimeInterval = 0.3) {
        let transition = CATransition()
        transition.duration = duration
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = type
        self.view.layer.addAnimation(transition, forKey: nil)
    }

}

11

ব্যক্তিগত কলগুলি ব্যবহার করা একটি খারাপ ধারণা কারণ অ্যাপল আর এমন অ্যাপ্লিকেশনগুলিকে অনুমোদন করে না। আপনি এটি চেষ্টা করতে পারে:

//Init Animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: 0.50];


[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.navigationController.view cache:YES];

//Create ViewController
MyViewController *myVC = [[MyViewController alloc] initWith...];

[self.navigationController pushViewController:myVC animated:NO];
[myVC release];

//Start Animation
[UIView commitAnimations];

এটি কেবল "অর্ধ" কাজ করে - এটি পপ অ্যানিমেশনগুলির শক্ত সমস্যা সমাধান করবে না।
আদম

আমি এই সমাধানটি আরও ভাল পছন্দ করি এবং হ্যাঁ এটি কার্যকর হয়। ব্যক্তিগত পদ্ধতি ব্যবহার করা আপনাকে নিশ্চিতভাবে প্রত্যাখ্যান করবে।
বেনজমিন ইন্তাল

@ নিকটমরো যা প্রাইভেট এপি কল। আমি কোন খেয়াল করিনি।
ফ্রাঙ্কলিন

@ ফ্র্যাঙ্কলিন কিছুক্ষণ আগে এখানে ব্যবহার করার আগে একটি আলোচনা হয়েছিল -pushViewController:transition:forceImmediate:যা একটি খারাপ ধারণা হবে।
নিকটমরো

9

যেহেতু গুগলে এটি শীর্ষ ফলাফল, আমি ভেবেছিলাম যে আমি যা বোধ করি তা সবচেয়ে বুদ্ধিমান উপায়; যা হ'ল আইওএস 7+ রূপান্তরকারী এপিআই ব্যবহার করা। আমি সুইফট 3 সহ আইওএস 10 এর জন্য এটি প্রয়োগ করেছি।

প্রোটোকলের সাথে সামঞ্জস্যপূর্ণ এমন কোনও শ্রেণীর একটি উপস্থাপনা UINavigationControllerতৈরি করে যদি আপনি একটি সাবক্লাস তৈরি করেন UINavigationControllerএবং দু'টি ভিউ কন্ট্রোলারের মধ্যে কীভাবে অ্যানিমেট করে তার সাথে এটি একত্রিত করা খুব সহজ UIViewControllerAnimatedTransitioning

উদাহরণস্বরূপ এখানে আমার UINavigationControllerসাবক্লাসটি রয়েছে:

class NavigationController: UINavigationController {
    init() {
        super.init(nibName: nil, bundle: nil)

        delegate = self
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension NavigationController: UINavigationControllerDelegate {

    public func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return NavigationControllerAnimation(operation: operation)
    }

}

আপনি দেখতে পাচ্ছেন যে আমি UINavigationControllerDelegateনিজেই এটি সেট করে রেখেছি এবং আমার সাবক্লাসে একটি এক্সটেনশনে আমি সেই পদ্ধতিটি প্রয়োগ করি UINavigationControllerDelegateযা আপনাকে একটি কাস্টম অ্যানিমেশন নিয়ন্ত্রণকারী (যেমন, NavigationControllerAnimation) ফেরত দিতে দেয় । এই কাস্টম অ্যানিমেশন নিয়ামক আপনার জন্য স্টক অ্যানিমেশন প্রতিস্থাপন করবে।

আপনি সম্ভবত ভাবছেন যে আমি কেন NavigationControllerAnimationএটির আরম্ভকারীটির মাধ্যমে অপারেশনটিতে উদাহরণটিতে পৌঁছে দেব । আমি এটি এমনটি করি যাতে প্রোটোকলের NavigationControllerAnimationপ্রয়োগে UIViewControllerAnimatedTransitioningআমি জানি যে অপারেশনটি কী (যেমন, 'পুশ' বা 'পপ')। এটি আমার কী ধরণের অ্যানিমেশন করা উচিত তা জানতে সহায়তা করে। বেশিরভাগ সময়, আপনি অপারেশনের উপর নির্ভর করে একটি আলাদা অ্যানিমেশন সম্পাদন করতে চান।

বাকিটা বেশ মানসম্পন্ন। UIViewControllerAnimatedTransitioningপ্রোটোকলে দুটি প্রয়োজনীয় ফাংশন বাস্তবায়ন করুন এবং আপনার পছন্দ মতো অ্যানিমেট করুন:

class NavigationControllerAnimation: NSObject, UIViewControllerAnimatedTransitioning {

    let operation: UINavigationControllerOperation

    init(operation: UINavigationControllerOperation) {
        self.operation = operation

        super.init()
    }

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

    public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from),
            let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else { return }
        let containerView = transitionContext.containerView

        if operation == .push {
            // do your animation for push
        } else if operation == .pop {
            // do your animation for pop
        }
    }
}

এটি মনে রাখা গুরুত্বপূর্ণ, যে প্রতিটি পৃথক প্রকারের ক্রিয়াকলাপের জন্য (যেমন, 'পুশ' বা 'পপ), এবং নিয়ন্ত্রকগুলির দৃষ্টিগোচর আলাদা হবে। আপনি যখন একটি পুশ অপারেশনে থাকবেন, তখন দেখার নিয়ামকটি সেই ধাক্কা দেওয়া হবে। আপনি যখন কোনও পপ অপারেশনে থাকবেন তখন দেখার জন্য নিয়ামকটি সেইটিতে স্থানান্তরিত হবে এবং ভিউ কন্ট্রোলারটি পপ করা হচ্ছে।

এছাড়াও, রূপান্তর প্রসঙ্গে toভিউ কন্ট্রোলারের অবশ্যই একটি সংক্ষিপ্তসার হিসাবে যুক্ত করা উচিত containerView

যখন আপনার অ্যানিমেশনটি সম্পূর্ণ হবে, আপনাকে অবশ্যই কল করতে হবে transitionContext.completeTransition(true)। আপনি একটি ইন্টারেক্টিভ রূপান্তরটি করছেন হয়, আপনি পরিবর্তনশীল একটি ফিরতি করতে হবে Boolকরতে completeTransition(didComplete: Bool)রূপান্তরটি অ্যানিমেশন শেষে সম্পূর্ণ হলে তার উপর নির্ভর করে।

শেষ অবধি ( readingচ্ছিক পড়া ), আপনি দেখতে চান যে আমি যে রূপান্তরটি নিয়ে কাজ করছি তা কীভাবে করেছি। এই কোডটি কিছুটা বেশি হ্যাকি এবং আমি এটি খুব তাড়াতাড়ি লিখেছি যাতে আমি এটি দুর্দান্ত অ্যানিমেশন কোড না বলি তবে এটি এখনও অ্যানিমেশন অংশটি কীভাবে করতে হয় তা দেখায়।

আমার একটি সত্যই সরল স্থানান্তর ছিল; আমি ইউআইএনএভিগেশন কন্ট্রোলার সাধারণত একই অ্যানিমেশনটি নকল করতে চেয়েছিলাম, তবে এটি 'শীর্ষ পৃষ্ঠার উপরের পৃষ্ঠা' অ্যানিমেশনটির পরিবর্তে আমি পুরানো ভিউ নিয়ামকের একটি 1: 1 অ্যানিমেশনটি নতুন দর্শন হিসাবে একই সময়ে বাস্তবায়ন করতে চেয়েছিলাম নিয়ামক উপস্থিত হয়। এটি দুটি ভিউ নিয়ন্ত্রককে একে অপরের সাথে পিন করা মনে হয় এমন করে তোলে।

পুশ অপারেশনের জন্য, প্রথমে toViewControllerx – অক্ষ থেকে স্ক্রিনের দর্শন উত্সটি সেট করা দরকার containerView, এটিকে origin.xশূন্যে সেট করে স্ক্রিনে এনিমেট করে , এর উপদর্শন হিসাবে যুক্ত করা উচিত । একই সময়ে, আমি স্ক্রিনটি বন্ধ করে fromViewControllerদিয়ে এর দৃশ্য দূরে সঞ্চারিত করছি origin.x:

toViewController.view.frame = containerView.bounds.offsetBy(dx: containerView.frame.size.width, dy: 0.0)

containerView.addSubview(toViewController.view)

UIView.animate(withDuration: transitionDuration(using: transitionContext),
               delay: 0,
               options: [ UIViewAnimationOptions.curveEaseOut ],
               animations: {
                toViewController.view.frame = containerView.bounds
                fromViewController.view.frame = containerView.bounds.offsetBy(dx: -containerView.frame.size.width, dy: 0)
},
               completion: { (finished) in
                transitionContext.completeTransition(true)
})

পপ অপারেশনটি মূলত বিপরীত। যোগ toViewControllerএকটি subview যেমন containerView, এবং দূরে সজীব fromViewControllerডানদিকে যেমন আপনি সজীব toViewControllerবাঁ দিক থেকে:

containerView.addSubview(toViewController.view)

UIView.animate(withDuration: transitionDuration(using: transitionContext),
               delay: 0,
               options: [ UIViewAnimationOptions.curveEaseOut ],
               animations: {
                fromViewController.view.frame = containerView.bounds.offsetBy(dx: containerView.frame.width, dy: 0)
                toViewController.view.frame = containerView.bounds
},
               completion: { (finished) in
                transitionContext.completeTransition(true)
})

পুরো সুইফ্ট ফাইলটি সহ এখানে একটি সংক্ষেপ:

https://gist.github.com/alanzeino/603293f9da5cd0b7f6b60dc20bc766be


গ্রেট !. আমি যা করতে চেয়েছিলাম তা হ'ল বিপরীত দিক থেকে প্রাণবন্ত হওয়া। আমি কিছু অন্যান্য সমাধান পরীক্ষা করেছি, তবে সমস্ত বাম এবং ডান স্ক্রিনে ঝলকানি দেখায়। দেখে মনে হচ্ছে যেন তাদের সাথে অন্তর্নিহিত আলফা পরিবর্তন অ্যানিমেশনটি সরানো যায় না। কেবলমাত্র এই সমাধানই সমস্যাটিকে সংশোধন করেছে।
বেশিও

হ্যাঁ, এটিই একমাত্র সঠিক আধুনিক সমাধান। (আমি কিছু মনে করি না, তবে এটি নীচে আমি যে সমাধানটি লিখেছি ঠিক ঠিক সেই একই!))
ফ্যাটি

@ অ্যালানজেইনো যদি একই ভিউকন্ট্রোলারের ভিতরে থাকে তবে বিভিন্ন বোতামের ক্লিকের জন্য আপনার ডাইফ্রেন্ট অ্যানিমেশন থাকা দরকার? সুতরাং, বোতাম 1 এর জন্য আপনার দ্রবীভূত অ্যানিমেশন প্রয়োজন, বাটন 2 এর জন্য আপনার ডিফল্ট রূপান্তর দরকার।
জেজেফেরিনো

7

সেখানে ইউআইএনএভিগেশন কন্ট্রোলারডেলিগেট এবং ইউআইভিউউকন্ট্রোলার অ্যানিমেটেড ট্রান্সশিশন রয়েছে সেখানে আপনি যা খুশি তাই অ্যানিমেশন পরিবর্তন করতে পারবেন।

উদাহরণস্বরূপ এটি ভিসির জন্য উল্লম্ব পপ অ্যানিমেশন:

@objc class PopAnimator: NSObject, UIViewControllerAnimatedTransitioning {

func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
    return 0.5
}

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

    let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
    let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
    let containerView = transitionContext.containerView()
    let bounds = UIScreen.mainScreen().bounds
    containerView!.insertSubview(toViewController.view, belowSubview: fromViewController.view)
    toViewController.view.alpha = 0.5

    let finalFrameForVC = fromViewController.view.frame

    UIView.animateWithDuration(transitionDuration(transitionContext), animations: {
        fromViewController.view.frame = CGRectOffset(finalFrameForVC, 0, bounds.height)
        toViewController.view.alpha = 1.0
        }, completion: {
            finished in
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
    })
}

}

এবং তারপর

func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    if operation == .Pop {
        return PopAnimator()
    }
    return nil;
}

দরকারী টিউটোরিয়াল https://www.objc.io/issues/5-ios7/view-controller-transitions/


6

দ্রুত উত্তর 4 এর জন্য আপডেট করা উত্তরের ভিত্তিতেjordanperry

ধাক্কা জন্য UIViewController

let yourVC = self.storyboard?.instantiateViewController(withIdentifier: "yourViewController") as! yourViewController
    UIView.animate(withDuration: 0.75, animations: {() -> Void in
    UIView.setAnimationCurve(.easeInOut)
    self.navigationController?.pushViewController(terms, animated: true)
    UIView.setAnimationTransition(.flipFromRight, for: (self.navigationController?.view)!, cache: false)
})

পপ জন্য

UIView.animate(withDuration: 0.75, animations: {() -> Void in
    UIView.setAnimationCurve(.easeInOut)
    UIView.setAnimationTransition(.flipFromLeft, for: (self.navigationController?.view)!, cache: false)
})
navigationController?.popViewController(animated: false)

5

সুইফটে আমি কীভাবে একইভাবে করেছি:

পুশের জন্য:

    UIView.animateWithDuration(0.75, animations: { () -> Void in
        UIView.setAnimationCurve(UIViewAnimationCurve.EaseInOut)
        self.navigationController!.pushViewController(nextView, animated: false)
        UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromRight, forView: self.navigationController!.view!, cache: false)
    })

পপ জন্য:

আমি উপরের কিছু প্রতিক্রিয়ার সাথে এটি কিছুটা ভিন্নভাবে করেছি - তবে আমি সুইফট বিকাশে নতুন হিসাবে, এটি সঠিক নাও হতে পারে। আমি ওভাররাইড viewWillDisappear:animated:করে সেখানে পপ কোড যুক্ত করেছি:

    UIView.animateWithDuration(0.75, animations: { () -> Void in
        UIView.setAnimationCurve(UIViewAnimationCurve.EaseInOut)
        UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromLeft, forView: self.navigationController!.view, cache: false)
    })

    super.viewWillDisappear(animated)

5

সুইচ ৪.২-এ @ লুকা দাভানজোর উত্তর

public extension UINavigationController {

    /**
     Pop current view controller to previous view controller.

     - parameter type:     transition animation type.
     - parameter duration: transition animation duration.
     */
    func pop(transitionType type: CATransitionType = .fade, duration: CFTimeInterval = 0.3) {
        self.addTransition(transitionType: type, duration: duration)
        self.popViewController(animated: false)
    }

    /**
     Push a new view controller on the view controllers's stack.

     - parameter vc:       view controller to push.
     - parameter type:     transition animation type.
     - parameter duration: transition animation duration.
     */
    func push(viewController vc: UIViewController, transitionType type: CATransitionType = .fade, duration: CFTimeInterval = 0.3) {
        self.addTransition(transitionType: type, duration: duration)
        self.pushViewController(vc, animated: false)
    }

    private func addTransition(transitionType type: CATransitionType = .fade, duration: CFTimeInterval = 0.3) {
        let transition = CATransition()
        transition.duration = duration
        transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
        transition.type = type
        self.view.layer.add(transition, forKey: nil)
    }

}

4

আমি সম্প্রতি অনুরূপ কিছু করার চেষ্টা করছিলাম। আমি স্থির করেছি যে আমি ইউআইএনএভিগেশন কন্ট্রোলারের স্লাইডিং অ্যানিমেশনটি পছন্দ করি না, তবে ইউআইভিউউ আপনাকে কার্ল বা এর মতো যে কোনও অ্যানিমেশন দেয় তা আমিও করতে চাইনি। আমি যখন চাপ দেই বা পপ করব তখন আমি দর্শনের মধ্যে ক্রস ফেইড করতে চাইতাম।

সেখানে সমস্যাটি এই সত্যটির সাথে জড়িত যে দৃশ্যটি আক্ষরিক অর্থে দর্শনটি সরিয়ে দিচ্ছে বা বর্তমানের শীর্ষের উপরে একটি পোপ করছে, সুতরাং বিবর্ণ কাজ করবে না। আমার নতুন দৃষ্টিভঙ্গিটি গ্রহণ এবং এটি ইউআইভিউউকন্ট্রোলারের স্ট্যাকের বর্তমান শীর্ষ দৃষ্টিভঙ্গির একটি সংক্ষিপ্তসার হিসাবে যুক্ত করার সমাধানটিতে আমি এসেছি। আমি এটি 0 এর একটি আলফা দিয়ে যুক্ত করব, তারপরে ক্রসফেইড করুন। যখন অ্যানিমেশন ক্রমটি শেষ হয়, আমি দৃশটিকে এনিমাইটিটে না করে স্ট্যাকের উপরে ঠেলা দিই। তারপরে আমি পুরানো টপভিউতে ফিরে যাই এবং আমার পরিবর্তিত জিনিসগুলি সাফ করি clean

এটি তার থেকে কিছুটা জটিল, কারণ আপনার কাছে নেভিগেশন আইটেমগুলি রূপান্তরটি সঠিক দেখানোর জন্য সামঞ্জস্য করতে হবে। এছাড়াও, আপনি যদি কোনও ঘূর্ণন করেন তবে আপনাকে সাবউভিউ হিসাবে ভিউগুলি যুক্ত করার সাথে সাথে ফ্রেমের আকারগুলি সামঞ্জস্য করতে হবে যাতে তারা স্ক্রিনে সঠিকভাবে প্রদর্শিত হয়। আমি ব্যবহার করা কিছু কোড এখানে of আমি ইউআইএনএভিগেশন কন্ট্রোলারকে সাবক্ল্যাস করেছি এবং পুশ এবং পপ পদ্ধতিগুলিকে ওভাররড করেছি।

-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
      UIViewController *currentViewController = [self.viewControllers lastObject];
      //if we don't have a current controller, we just do a normal push
      if(currentViewController == nil)
      {
         [super pushViewController:viewController animated:animated];
         return;
      }
      //if no animation was requested, we can skip the cross fade
      if(!animation)
      {
         [super pushViewController:viewController animated:NO];
         return;
      }
      //start the cross fade.  This is a tricky thing.  We basically add the new view
//as a subview of the current view, and do a cross fade through alpha values.
//then we push the new view on the stack without animating it, so it seemlessly is there.
//Finally we remove the new view that was added as a subview to the current view.

viewController.view.alpha = 0.0;
//we need to hold onto this value, we'll be releasing it later
    NSString *title = [currentViewController.title retain];

//add the view as a subview of the current view
[currentViewController.view addSubview:viewController.view];
[currentViewController.view bringSubviewToFront:viewController.view];
UIBarButtonItem *rButtonItem = currentViewController.navigationItem.rightBarButtonItem;
UIBarButtonItem *lButtonItem = currentViewController.navigationItem.leftBarButtonItem;

NSArray *array = nil;

//if we have a right bar button, we need to add it to the array, if not, we will crash when we try and assign it
//so leave it out of the array we are creating to pass as the context.  I always have a left bar button, so I'm not checking to see if it is nil. Its a little sloppy, but you may want to be checking for the left BarButtonItem as well.
if(rButtonItem != nil)
    array = [[NSArray alloc] initWithObjects:currentViewController,viewController,title,lButtonItem,rButtonItem,nil];
else {
    array = [[NSArray alloc] initWithObjects:currentViewController,viewController,title,lButtonItem,nil];
}

//remove the right bar button for our transition
[currentViewController.navigationItem setRightBarButtonItem:nil animated:YES];
//remove the left bar button and create a backbarbutton looking item
//[currentViewController.navigationItem setLeftBarButtonItem:nil animated:NO];

//set the back button
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:title style:kButtonStyle target:self action:@selector(goBack)];
[currentViewController.navigationItem setLeftBarButtonItem:backButton animated:YES];
[viewController.navigationItem setLeftBarButtonItem:backButton animated:NO];
[backButton release];

[currentViewController setTitle:viewController.title];

[UIView beginAnimations:@"push view" context:array];
[UIView setAnimationDidStopSelector:@selector(animationForCrossFadePushDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.80];
[viewController.view setAlpha: 1.0];
[UIView commitAnimations];
}

-(void)animationForCrossFadePushDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{

UIViewController *c = [(NSArray*)context objectAtIndex:0];
UIViewController *n = [(NSArray*)context objectAtIndex:1];
NSString *title     = [(NSArray *)context objectAtIndex:2];
UIBarButtonItem *l = [(NSArray *)context objectAtIndex:3];
UIBarButtonItem *r = nil;
//not all views have a right bar button, if we look for it and it isn't in the context,
//we'll crash out and not complete the method, but the program won't crash.
//So, we need to check if it is there and skip it if it isn't.
if([(NSArray *)context count] == 5)
    r = [(NSArray *)context objectAtIndex:4];

//Take the new view away from being a subview of the current view so when we go back to it
//it won't be there anymore.
[[[c.view subviews] lastObject] removeFromSuperview];
[c setTitle:title];
[title release];
//set the search button
[c.navigationItem setLeftBarButtonItem:l animated:NO];
//set the next button
if(r != nil)
    [c.navigationItem setRightBarButtonItem:r animated:NO];


[super pushViewController:n animated:NO];

 }

আমি কোডটিতে উল্লেখ করেছি, আমার সর্বদা একটি বাম বারের বোতাম আইটেম থাকে, তাই আমি অ্যানিমেশন প্রতিনিধিটির প্রসঙ্গ হিসাবে পাস করি এমন অ্যারেটিতে রাখার আগে এটি শূন্য হয় কিনা তা পরীক্ষা করে দেখছি না। আপনি যদি এটি করেন তবে আপনি এই চেকটি করতে চাইতে পারেন।

আমি যে সমস্যাটি পেয়েছি তা হ'ল আপনি যদি ডেলিগেট পদ্ধতিতে মোটেই ক্র্যাশ করেন তবে প্রোগ্রামটি ক্রাশ হবে না। এটি প্রতিনিধিটিকে সম্পূর্ণ করা থেকে বিরত করে তবে আপনি কোনও ধরণের সতর্কতা পান না।
সুতরাং যেহেতু আমি সেই প্রতিনিধি রুটিনে আমার ক্লিনআপটি করছিলাম তাই এটি ক্লিনআপটি শেষ না করায় এটি কিছু অদ্ভুত দৃশ্য আচরণের কারণ হয়ে উঠছিল।

আমি তৈরি করা পিছনের বোতামটি একটি "GoBack" পদ্ধতি কল করে এবং সেই পদ্ধতিটি কেবল পপ রুটিনকে কল করে।

-(void)goBack
{ 
     [self popViewControllerAnimated:YES];
}

এছাড়াও, এখানে আমার পপ রুটিন।

-(UIViewController *)popViewControllerAnimated:(BOOL)animated
{
    //get the count for the number of viewControllers on the stack
int viewCount = [[self viewControllers] count];
//get the top view controller on the stack
UIViewController *topViewController = [self.viewControllers objectAtIndex:viewCount - 1];
//get the next viewController after the top one (this will be the new top one)
UIViewController *newTopViewController = [self.viewControllers objectAtIndex:viewCount - 2];

//if no animation was requested, we can skip the cross fade
if(!animated)
{
    [super popViewControllerAnimated:NO];
            return topViewController;
}



//start of the cross fade pop.  A bit tricky.  We need to add the new top controller
//as a subview of the curent view controler with an alpha of 0.  We then do a cross fade.
//After that we pop the view controller off the stack without animating it.
//Then the cleanup happens: if the view that was popped is not released, then we
//need to remove the subview we added and change some titles back.
newTopViewController.view.alpha = 0.0;
[topViewController.view addSubview:newTopViewController.view];
[topViewController.view bringSubviewToFront:newTopViewController.view];
NSString *title = [topViewController.title retain];
UIBarButtonItem *lButtonItem = topViewController.navigationItem.leftBarButtonItem;
UIBarButtonItem *rButtonItem = topViewController.navigationItem.rightBarButtonItem;

//set the new buttons on top of the current controller from the new top controller
if(newTopViewController.navigationItem.leftBarButtonItem != nil)
{
    [topViewController.navigationItem setLeftBarButtonItem:newTopViewController.navigationItem.leftBarButtonItem animated:YES];
}
if(newTopViewController.navigationItem.rightBarButtonItem != nil)
{
    [topViewController.navigationItem setRightBarButtonItem:newTopViewController.navigationItem.rightBarButtonItem animated:YES];
}

[topViewController setTitle:newTopViewController.title];
//[topViewController.navigationItem.leftBarButtonItem setTitle:newTopViewController.navigationItem.leftBarButtonItem.title];

NSArray *array = nil;
if(rButtonItem != nil)
    array = [[NSArray alloc] initWithObjects:topViewController,title,lButtonItem,rButtonItem,nil];
else {
    array = [[NSArray alloc] initWithObjects:topViewController,title,lButtonItem,nil];
}


[UIView beginAnimations:@"pop view" context:array];
[UIView setAnimationDidStopSelector:@selector(animationForCrossFadePopDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.80];
[newTopViewController.view setAlpha: 1.0];
[UIView commitAnimations];
return topViewController;

 }

 -(void)animationForCrossFadePopDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
 {

UIViewController *c = [(NSArray *)context objectAtIndex:0];
//UIViewController *n = [(NSArray *)context objectAtIndex:1];
NSString *title = [(NSArray *)context objectAtIndex:1];
UIBarButtonItem *l = [(NSArray *)context objectAtIndex:2];
UIBarButtonItem *r = nil;



//Not all views have a right bar button.  If we look for one that isn't there
// we'll crash out and not complete this method, but the program will continue.
//So we need to check if it is therea nd skip it if it isn't.
if([(NSArray *)context count] == 4)
    r = [(NSArray *)context objectAtIndex:3];

//pop the current view from the stack without animation
[super popViewControllerAnimated:NO];

//if what was the current veiw controller is not nil, then lets correct the changes
//we made to it.
if(c != nil)
{
    //remove the subview we added for the transition
    [[c.view.subviews lastObject] removeFromSuperview];
    //reset the title we changed
    c.title = title;
    [title release];
    //replace the left bar button that we changed
    [c.navigationItem setLeftBarButtonItem:l animated:NO];
    //if we were passed a right bar button item, replace that one as well
    if(r != nil)
        [c.navigationItem setRightBarButtonItem:r animated:NO];
    else {
        [c.navigationItem setRightBarButtonItem:nil animated:NO];
    }


 }
}

যে প্রায় কাছাকাছি এটা. আপনি যদি আবর্তনগুলি প্রয়োগ করতে চান তবে আপনাকে কিছু অতিরিক্ত কোডের প্রয়োজন হবে। আপনি আপনার দৃশ্যের ফ্রেম আকার সেট করে রাখতে হবে যা আপনি সাবউভিউগুলি যুক্ত করার আগে আপনাকে যুক্ত করেছেন অন্যথায় আপনি অভিব্যক্তিটি ল্যান্ডস্কেপ হিসাবে ইস্যুতে চালিত করবেন, তবে শেষ বার যখন আপনি আগের দৃশ্যটি দেখেছিলেন তখন এটি প্রতিকৃতি ছিল। সুতরাং, তারপরে আপনি এটিকে একটি উপদর্শন হিসাবে যুক্ত করুন এবং এটি বিবর্ণ করুন তবে এটি প্রতিকৃতি হিসাবে প্রদর্শিত হবে, তারপরে যখন আমরা অ্যানিমেশন ছাড়াই পপ করব, একই দৃশ্য, কিন্তু স্ট্যাকের মধ্যে থাকা একটি এখন ল্যান্ডস্কেপ। পুরো জিনিসটি কিছুটা মজাদার দেখাচ্ছে। প্রত্যেকের আবর্তনের বাস্তবায়ন কিছুটা আলাদা তাই আমি এর জন্য এখানে আমার কোডটি অন্তর্ভুক্ত করি নি।

আশা করি এটি কিছু লোককে সহায়তা করবে। আমি এই জাতীয় কিছু খুঁজছি এবং কিছুই খুঁজে পেল না। আমি মনে করি না এটি সঠিক উত্তর, তবে এই মুহুর্তে এটি আমার পক্ষে সত্যই কাজ করছে।


প্রশংসনীয় যাইহোক, এটি এখন সত্য নয় 7 বছর পরে সমাধান!
ফ্যাটি

তুমি ঠিক. এই উত্তরটি ছিল ২০১১ সাল থেকে। =)
জিয়ারিয়ান

4

আপনি এখন ব্যবহার করতে পারেন UIView.transition। নোট করুন animated:false। এটি কোনও রূপান্তর বিকল্প, পপ, পুশ, বা স্ট্যাক প্রতিস্থাপনের সাথে কাজ করে।

if let nav = self.navigationController
{
    UIView.transition(with:nav.view, duration:0.3, options:.transitionCrossDissolve, animations: {
        _ = nav.popViewController(animated:false)
    }, completion:nil)
}

1
@Fattie, এই বিশেষ পদ্ধতিটি কেবল তালিকাভুক্ত মান যেমন ফ্লিপ এবং কার্ল অ্যানিমেশন সাথে কাজ করে developer.apple.com/documentation/uikit/uiviewanimationoptions
পিটার DeWeese

3

আইজর্ডানের উত্তরটি অনুপ্রেরণা হিসাবে ব্যবহার করে, কেন আপনি পুরো জায়গায় এই অ্যানিমেশন কোডটি অনুলিপি / আটকানোর পরিবর্তে আপনার অ্যাপ্লিকেশন জুড়ে ইউআইএনএভিগেশন কন্ট্রোলারের উপর একটি বিভাগ তৈরি করবেন না?

UINavigationController + + Animation.h

@interface UINavigationController (Animation)

- (void) pushViewControllerWithFlip:(UIViewController*) controller;

- (void) popViewControllerWithFlip;

@end

UINavigationController + + Animation.m

@implementation UINavigationController (Animation)

- (void) pushViewControllerWithFlip:(UIViewController *) controller
{
    [UIView animateWithDuration:0.50
                     animations:^{
                         [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                         [self pushViewController:controller animated:NO];
                         [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
                     }];
}

- (void) popViewControllerWithFlip
{
    [UIView animateWithDuration:0.5
                     animations:^{
                         [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                         [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
                     }];

    [self popViewControllerAnimated:NO];
}

@end

তারপরে কেবল ইউআইএনএভিগেশন কন্ট্রোলার + অ্যানিমেশন.চ ফাইলটি আমদানি করুন এবং এটিকে সাধারণত কল করুন:

[self.navigationController pushViewControllerWithFlip:[[NewViewController alloc] init]];

[self.navigationController popViewControllerWithFlip];

চালাক। তবে কেন পুশ / পপ পদ্ধতি যুক্ত করবেন না যেগুলি ইউআইভিউএনিমেশন ট্রান্সশিশনের একটি যুক্তি ফ্লিপফ্রাইমরাইটের চেয়ে হার্ডকোডের পরিবর্তে গ্রহণ করবে?
জেফ

@ জিফ এই সুবিধাগুলি পদ্ধতি - এই পদ্ধতিতে, প্রতিটি নির্দিষ্ট অ্যানিমেশন প্রকারের জন্য কোন ইউআইভিউএনিমেশন ট্রান্সশন মানটি পাস করতে হবে তা প্রয়োগকারীকে মনে করার দরকার নেই, তারা কী অর্জন করতে চান তার নামটি "ইংরেজী" নাম দিয়ে কল করে।
ডিস্কদেভ

@ জেফ এছাড়াও, আপনার পরামর্শটি অবশ্যই কার্যকর - যদি আমি এখনও অবজেক্টিভি সি ব্যবহার করতাম এবং অনেকগুলি রূপান্তর শৈলী সমর্থন করার প্রয়োজন হত (অবশ্যই বিভিন্ন রূপান্তর শৈলী ব্যবহারকারীদের বিভ্রান্ত করবে বলে প্রস্তাবিত নয়) আমার 1 টি পদ্ধতি থাকবে যা ইউআইভিউএনিমেশন ট্রান্সিশন টাইপ নেয়, বিকাশকে আরও সহজ করার জন্য বেশ কয়েকটি সুবিধা পদ্ধতি।
ডিস্কদেব

3

এটা খুবই সাধারণ

self.navigationController?.view.semanticContentAttribute = .forceRightToLeft

স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম: আপনি যদি কোড, এক্সএমএল বা ডেটা নমুনাগুলি পোস্ট করেন তবে অনুগ্রহ করে টেক্সট সম্পাদকের সেই লাইনগুলি হাইলাইট করুন এবং সম্পাদনা সরঞ্জামদণ্ডে "কোড স্যাম্পল" বোতামটি ({click) ক্লিক করুন বা আপনার কীবোর্ডের সিআরটিএল + কে ব্যবহার করে সুন্দর বিন্যাস করুন এবং সিনট্যাক্স এটি হাইলাইট!
হোয়াটপয়েন্টে

2

ADTransitionController এ দেখুন , কাস্টম ট্রানজিশন অ্যানিমেশনগুলির সাথে ইউআইএনএভিগেশন কন্ট্রোলারের প্রতিস্থাপনের একটি ড্রপ (এটির এপিআই ইউআইএনএভিগেশন কন্ট্রোলারের API এর সাথে মেলে) যা আমরা অ্যাপ্লিডিয়ামে তৈরি করেছি।

আপনি পুশ এবং পপ ক্রিয়া যেমন সোয়াইপ , বিবর্ণ , কিউব , ক্যারোজেল , জুম এবং এর জন্য বিভিন্ন পূর্বনির্ধারিত অ্যানিমেশন ব্যবহার করতে পারেন ।


2

যদিও এখানে সমস্ত উত্তর দুর্দান্ত এবং বেশিরভাগ খুব ভাল কাজ করে, একটি সামান্য সরল পদ্ধতি রয়েছে যা একই প্রভাব অর্জন করে ...

পুশের জন্য:

  NextViewController *nextViewController = [[NextViewController alloc] init];

  // Shift the view to take the status bar into account 
  CGRect frame = nextViewController.view.frame;
  frame.origin.y -= 20;
  frame.size.height += 20;
  nextViewController.view.frame = frame;

  [UIView transitionFromView:self.navigationController.topViewController.view toView:nextViewController.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL finished) {
    [self.navigationController pushViewController:nextViewController animated:NO];
  }];

পপ জন্য:

  int numViewControllers = self.navigationController.viewControllers.count;
  UIView *nextView = [[self.navigationController.viewControllers objectAtIndex:numViewControllers - 2] view];

  [UIView transitionFromView:self.navigationController.topViewController.view toView:nextView duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) {
    [self.navigationController popViewControllerAnimated:NO];
  }];}

রুট ভিউ কন্ট্রোলারে পপ করার সময় এটি ক্রাশ হবে।
আব্দুল্লাহ উমার

1

আপনি কোনওভাবেই প্রকাশ্যে রূপান্তর অ্যানিমেশন পরিবর্তন করতে পারবেন তা সম্পর্কে আমি অবগত নই।

যদি "পিছনে" বোতামটি প্রয়োজনীয় না হয় আপনি "নীচ থেকে ধাক্কা" / "ফ্লিপ" / "বিবর্ণ" / (≥3.2) "পৃষ্ঠা কার্ল" ট্রানজিশনগুলির জন্য মডেল ভিউ কন্ট্রোলার ব্যবহার করা উচিত


উপর ব্যক্তিগত পার্শ্ব, পদ্ধতি -pushViewController:animated:অনথিভুক্ত পদ্ধতি আহ্বান -pushViewController:transition:forceImmediate:, তাই যেমন আপনি একটি উল্টানো-থেকে-বাম-থেকে-ডান রূপান্তরটি, আপনি ব্যবহার করতে পারেন চান

[navCtrler pushViewController:ctrler transition:10 forceImmediate:NO];

তবে আপনি "পপ" রূপান্তরটি এভাবে পরিবর্তন করতে পারবেন না।


1

কোডের খুব কম লাইনে এটি করার একটি উপায়ের জন্য এই প্রশ্নের আমার উত্তরটি দেখুন । এই পদ্ধতিটি আপনাকে আপনার পছন্দমতো কোনও নতুন ভিউ কন্ট্রোলারের সিউডো- "পুশ" অ্যানিমেট করার অনুমতি দেয় এবং অ্যানিমেশনটি সম্পন্ন হওয়ার পরে এটি নেভিগেশন কন্ট্রোলারটিকে ঠিকঠাক করে দেয় যেমন আপনি স্ট্যান্ডার্ড পুশ পদ্ধতিটি ব্যবহার করেছেন। আমার উদাহরণ আপনাকে বাম থেকে বা ডান দিক থেকে একটি স্লাইড-ইন সঞ্চার করতে দেয়। সুবিধার জন্য এখানে কোড পুনরাবৃত্তি:

-(void) showVC:(UIViewController *) nextVC rightToLeft:(BOOL) rightToLeft {
    [self addChildViewController:neighbor];
    CGRect offscreenFrame = self.view.frame;
    if(rightToLeft) {
        offscreenFrame.origin.x = offscreenFrame.size.width * -1.0;
    } else if(direction == MyClimbDirectionRight) {
        offscreenFrame.origin.x = offscreenFrame.size.width;
    }
    [[neighbor view] setFrame:offscreenFrame];
    [self.view addSubview:[neighbor view]];
    [neighbor didMoveToParentViewController:self];
    [UIView animateWithDuration:0.5 animations:^{
        [[neighbor view] setFrame:self.view.frame];
    } completion:^(BOOL finished){
        [neighbor willMoveToParentViewController:nil];
        [neighbor.view removeFromSuperview];
        [neighbor removeFromParentViewController];
        [[self navigationController] pushViewController:neighbor animated:NO];
        NSMutableArray *newStack = [[[self navigationController] viewControllers] mutableCopy];
        [newStack removeObjectAtIndex:1]; //self, just below top
        [[self navigationController] setViewControllers:newStack];
    }];
}

0

নমুনা অ্যাপ্লিকেশন থেকে, এই প্রকরণটি দেখুন। https://github.com/mpospese/MPFoldTransition/

#pragma mark - UINavigationController(MPFoldTransition)

@implementation UINavigationController(MPFoldTransition)

//- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
- (void)pushViewController:(UIViewController *)viewController foldStyle:(MPFoldStyle)style
{
    [MPFoldTransition transitionFromViewController:[self visibleViewController] 
                                  toViewController:viewController 
                                          duration:[MPFoldTransition defaultDuration]  
                                             style:style 
                                        completion:^(BOOL finished) {
                                            [self pushViewController:viewController animated:NO];
                                        }
     ];
}

- (UIViewController *)popViewControllerWithFoldStyle:(MPFoldStyle)style
{
    UIViewController *toController = [[self viewControllers] objectAtIndex:[[self viewControllers] count] - 2];

    [MPFoldTransition transitionFromViewController:[self visibleViewController] 
                                  toViewController:toController 
                                          duration:[MPFoldTransition defaultDuration] 
                                             style:style
                                        completion:^(BOOL finished) {
                                            [self popViewControllerAnimated:NO];
                                        }
     ];

    return toController;
}

0

শুধু ব্যবহার করুন:

ViewController *viewController = [[ViewController alloc] init];

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
navController.navigationBarHidden = YES;

[self presentViewController:navController animated:YES completion: nil];
[viewController release];
[navController release];

0

এটি উপলব্ধি করা একটি পুরানো প্রশ্ন। আমি এখনও এই উত্তরটি পোস্ট করতে চাই, কারণ viewControllersপ্রস্তাবিত উত্তরগুলির সাথে বেশ কয়েকটি পপ করতে আমার কিছু সমস্যা হয়েছিল । আমার সমাধান হ'ল সাবক্লাস UINavigationControllerএবং সমস্ত পপ এবং পুশ পদ্ধতিগুলিকে ওভাররাইড করা।

FlippingNavigationController.h

@interface FlippingNavigationController : UINavigationController

@end

FlippingNavigationController.m:

#import "FlippingNavigationController.h"

#define FLIP_DURATION 0.5

@implementation FlippingNavigationController

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [UIView transitionWithView:self.view
                      duration:animated?FLIP_DURATION:0
                       options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionFlipFromRight
                    animations:^{ [super pushViewController:viewController
                                                   animated:NO]; }
                    completion:nil];
}

- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
    return [[self popToViewController:[self.viewControllers[self.viewControllers.count - 2]]
                             animated:animated] lastObject];
}

- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated
{
    return [self popToViewController:[self.viewControllers firstObject]
                            animated:animated];
}

- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    __block NSArray* viewControllers = nil;

    [UIView transitionWithView:self.view
                      duration:animated?FLIP_DURATION:0
                       options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionFlipFromLeft
                    animations:^{ viewControllers = [super popToViewController:viewController animated:NO]; }
                    completion:nil];

    return viewControllers;
}

@end

0

আমি জানি এই থ্রেডটি পুরানো, তবে আমি ভেবেছিলাম আমার দুটি সেন্ট লাগিয়ে দেব। আপনার একটি কাস্টম অ্যানিমেশন তৈরি করার দরকার নেই, এটি করার একটি সহজ (সম্ভবত হ্যাকি) উপায় রয়েছে। পুশ ব্যবহারের পরিবর্তে, একটি নতুন নেভিগেশন কন্ট্রোলার তৈরি করুন, নতুন ভিউ কন্ট্রোলারটিকে সেই এনএভি কন্ট্রোলারের রুট ভিউ কন্ট্রোলার করুন এবং তারপরে মূল এনএভি কন্ট্রোলার থেকে এনএভি কন্ট্রোলার উপস্থাপন করুন। উপস্থাপনাটি অনেকগুলি শৈলীর সাথে সহজেই কাস্টমাইজযোগ্য এবং কাস্টম অ্যানিমেশন করার প্রয়োজন নেই।

উদাহরণ স্বরূপ:

UIViewcontroller viewControllerYouWantToPush = UIViewController()
UINavigationController newNavController = UINavigationController(root: viewControllerYouWantToView)
newNavController.navBarHidden = YES;
self.navigationController.present(newNavController)

এবং আপনি চাইলে উপস্থাপনা শৈলী পরিবর্তন করতে পারেন।


-1

আমি এটি করার জন্য একটি হালকা পুনরাবৃত্তির উপায় পেয়েছি যা আমার উদ্দেশ্যে কাজ করে। আমার কাছে একটি উদাহরণ ভেরিয়েবল BOOL রয়েছে যা আমি সাধারণ পপিং অ্যানিমেশনটি ব্লক করতে এবং আমার নিজের অ অ্যানিমেটেড পপ বার্তাকে বিকল্প হিসাবে ব্যবহার করতে ব্যবহার করি। ভেরিয়েবলটি প্রথমে NO এ সেট করা আছে। যখন পিছনের বোতামটি ট্যাপ করা হয়, তখন প্রতিনিধি পদ্ধতিটি এটি হ্যাঁ সেট করে এবং এনএভি বারে একটি নতুন অ-অ্যানিমেটেড পপ বার্তা প্রেরণ করে, ততক্ষণে আবার একই প্রতিনিধি পদ্ধতিটিকে কল করে, এই মুহুর্তে হ্যাঁ চলকটি সেট করে। ভেরিয়েবলটি হ্যাঁ সেট করা হয়েছে, প্রতিনিধি পদ্ধতিটি এটি NO তে সেট করে এবং অ-অ্যানিমেটেড পপটি ঘটতে দিতে হ্যাঁ প্রদান করে। দ্বিতীয় প্রতিনিধি কল রিটার্নের পরে, আমরা প্রথমটিতে ফিরে আসি, যেখানে কোনও ফিরে আসে না, আসল অ্যানিমেটেড পপটিকে অবরুদ্ধ করে! এটি যতটা শোনাচ্ছে ততটা অগোছালো নয়। আমার shouldPopItem পদ্ধতিটি দেখতে এমন দেখাচ্ছে:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item 
{
    if ([[navigationBar items] indexOfObject:item] == 1) 
    {
        [expandedStack restack];    
    }

    if (!progPop) 
    {
        progPop = YES;
        [navBar popNavigationItemAnimated:NO];
        return NO;
    }
    else 
    {
        progPop = NO;
        return YES;
    }
}

আমার জন্য কাজ কর.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.