কোনও ভিউ কন্ট্রোলার কোনও মডেলভাবে উপস্থাপিত হয়েছে বা নেভিগেশন স্ট্যাকের দিকে ধাক্কা দিচ্ছে কিনা তা কীভাবে পরীক্ষা করবেন?


126

আমি কীভাবে, আমার দর্শন নিয়ামক কোডে, এর মধ্যে পার্থক্য করতে পারি:

  • পরিমিতভাবে উপস্থাপন
  • নেভিগেশন স্ট্যাকের দিকে ধাক্কা

উভয় presentingViewControllerএবং isMovingToParentViewControllerহয় YESউভয় ক্ষেত্রেই, তাই খুব সহায়ক নয়।

জিনিসগুলিকে কী জটিল করে তোলে তা হ'ল আমার পিতা বা মাতা ভিউ কন্ট্রোলারটি মাঝেমধ্যে মডেল হয়, যার উপরে চেক করা ভিউ নিয়ন্ত্রণকারীকে চাপ দেওয়া হয়।

এটি সক্রিয় আউট আমার সমস্যা যে আমি আমার এম্বেড হয় HtmlViewControllerএকটি UINavigationControllerযা পরে উপস্থাপন করা হয়। সে কারণেই আমার নিজের প্রচেষ্টা এবং নীচের ভাল উত্তরগুলি কাজ করছে না।

HtmlViewController*     termsViewController = [[HtmlViewController alloc] initWithDictionary:dictionary];
UINavigationController* modalViewController;

modalViewController = [[UINavigationController alloc] initWithRootViewController:termsViewController];
modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:modalViewController
                   animated:YES
                 completion:nil];

আমি অনুমান করি যে আমি আমার দৃশ্যের নিয়ামকটি যখন মডেল হয় তখন এটি নির্ধারণের পরিবর্তে আরও ভাল বলতে পারি tell

উত্তর:


125

নুনের দানা নিয়ে নিন, পরীক্ষা করেননি।

- (BOOL)isModal {
     if([self presentingViewController])
         return YES;
     if([[[self navigationController] presentingViewController] presentedViewController] == [self navigationController])
         return YES;
     if([[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]])
         return YES;

    return NO;
 }

12
আমি এটি অন্য এসও পোস্টে পেয়েছি। তবে, ধাক্কা দেওয়া ভিউ কন্ট্রোলারের পিতা-মাতা মডেল হলে কাজ করে না; আমার যে পরিস্থিতি হচ্ছে
অর্থ-বিষয়গুলি

2
আমি যেমন লিখেছি, presentingViewControllerসর্বদা YESআমার ক্ষেত্রে; সাহায্য করে না।
অর্থ-বিষয়গুলি

3
presentingViewControllerYESযখন UITabBarControllerকোনও রুট হিসাবে সেট করা থাকে তখন ধাক্কা ভিসির পক্ষে ফিরে আসে । সুতরাং, আমার ক্ষেত্রে উপযুক্ত নয়।
ইয়েভেন ডাবিনিন

5
যদি আপনি কোনও ভিউ কন্ট্রোলার উপস্থাপন করেন তবে এটি কাজ করে না তবে এটি অন্যটিকে ধাক্কা দেয়।
লি

3
"যদি আপনি কোনও ভিউ কন্ট্রোলার উপস্থাপন করেন তবে এটি কাজ করে না তবে এটি অন্য একজনকে ধাক্কা দেয়" এটি এর উদ্দেশ্য নয়, পুশ ভিউ কন্ট্রোলার উপস্থাপন করা হচ্ছে না।
কলিন সোয়েলিন

87

ইন সুইফট :

এটি শ্রেণীর ধরণের দ্বারা মডেল হলে পরীক্ষার জন্য একটি পতাকা যুক্ত করুন:

// MARK: - UIViewController implementation

extension UIViewController {

    var isModal: Bool {

        let presentingIsModal = presentingViewController != nil
        let presentingIsNavigation = navigationController?.presentingViewController?.presentedViewController == navigationController
        let presentingIsTabBar = tabBarController?.presentingViewController is UITabBarController

        return presentingIsModal || presentingIsNavigation || presentingIsTabBar
    }
}

4
কোনও var isModal: Bool {}
ভেরিতে

1
@ ললিনোয়াইস পরিবর্তিত হয়েছে
ইয়ানস্টেফ

বিবৃতিতে সর্বশেষ falseপ্যারামিটারটি কী করে return?
দামাজান্দ

আপনার আইসন্যাভিগেশন = নেভিগেশন কনট্রোলার? প্রিপ্রেসিংভিউ কনক্রোলার? প্রেজেন্টভিউ ভিউকন্ট্রোলার == নেভিগেশনকন্ট্রোলার এবং & নেভিগেশন কন্ট্রোলার! =
শুক্র

78

আপনি এক পদ্ধতি উপেক্ষিত: isBeingPresented

isBeingPresented ভিউ কন্ট্রোলার যখন উপস্থাপন করা হচ্ছে এবং যখন ধাক্কা দেওয়া হচ্ছে তখন এটি সত্য।

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if ([self isBeingPresented]) {
        // being presented
    } else if ([self isMovingToParentViewController]) {
        // being pushed
    } else {
        // simply showing again because another VC was dismissed
    }
}

2
আমি এই চেষ্টা খুব পোস্ট করার আগে, এবং এটি কাজ করে না, isBeingPresentedহয় NO। তবে আমি এখন কারণটি দেখতে পাচ্ছি, আমি আমার উপস্থাপিত ভিউ কন্ট্রোলারটিকে এম্বেড করছি UINavigationControllerএবং এটিই আমি চাপ দিচ্ছি।
অর্থ-বিষয়গুলি

1
আপনি কোনও নেভিগেশন নিয়ামককে ঠেলাতে পারবেন না। সম্ভবত আপনি বোঝাতে চেয়েছিলেন যে আপনি নেভিগেশন নিয়ন্ত্রক উপস্থাপন করছেন।
rmaddy

3
@ জুই ব্যবহার করুন p, poকোনও আদিম মান মুদ্রণের সময় নয় । poমুদ্রণ অবজেক্টের জন্য।
rmaddy

37
এর জন্য ডকুমেন্টেশন isBeingPresented- এই পদ্ধতিটি কেবলমাত্র ভিউইল অ্যাপয়ার: এবং ভিউডিডঅ্যাপার: পদ্ধতিগুলির ভিতরে থেকে ডেকে এলে হ্যাঁ দেয়।
funct7

4
@ টেরেন্স এটি সর্বশেষতম ডকুমেন্টেশনগুলি সেই তথ্যটি প্রদর্শন করে না তবে এটি সেখানে ব্যবহৃত হত। isBeingPresented, isBeingDismissed, isMovingFromParentViewControllerএবং isMovingToParentViewController4 ভিতরে শুধুমাত্র বৈধ view[Will|Did][Disa|A]ppearপদ্ধতি।
rmaddy

29

সুইফট 5
এখানে এমন সমাধান রয়েছে যা পূর্ববর্তী উত্তরগুলির সাথে উল্লিখিত ইস্যুটিকে সম্বোধন করে, যখন কোনও উপস্থাপিত স্ট্যাকের মধ্যে ধাক্কা দেওয়া হলে isModal()ফেরত trueদেওয়া UIViewControllerহয় UINavigationController

extension UIViewController {
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            return true
        } else if navigationController?.presentingViewController?.presentedViewController == navigationController {
            return true
        } else if tabBarController?.presentingViewController is UITabBarController {
            return true
        } else {
            return false
        }
    }
}

এটি এখনও পর্যন্ত আমার পক্ষে কাজ করে। কিছু অপ্টিমাইজেশন হলে, শেয়ার করুন।


আপনার চেক করা দরকার কেন tabBarController?.presentingViewController is UITabBarController ? এটি যদি presentingViewControllerকোনও ইউআইটিববারকন্ট্রোলার হয় তবে কী তা বিবেচনা করে?
হ্লুং

এবং যদি নেভিগেশনকন্ট্রোলার শূন্য থাকে তবে isModalফিরে আসবে true। এটা কি উদ্দেশ্য?
হ্লুং

28

self.navicationController! = নিল মানে এটি নেভিগেশন স্ট্যাকের মধ্যে রয়েছে।

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

extension UIViewController {
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            return true
        } else if let navigationController = navigationController, navigationController.presentingViewController?.presentedViewController == navigationController {
            return true
        } else if let tabBarController = tabBarController, tabBarController.presentingViewController is UITabBarController {
            return true
        } else {
            return false
        }
    }
}

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

ভাল কাজ যা সমস্ত ব্যবহারের ক্ষেত্রে ডিল করে। কিছুটা রিফ্যাক্টরিং করার জন্য সম্ভবত সম্ভবত এখনও তবুও!
জিন রেমন্ড দাহের 16

12

সুইফট 4

var isModal: Bool {
    return presentingViewController != nil ||
           navigationController?.presentingViewController?.presentedViewController === navigationController ||
           tabBarController?.presentingViewController is UITabBarController
}

সুইফট ৪.২ / আইওএস ১২. এখনও ভাল কাজ করে তবে সচেতন থাকুন নেভিগেশনকন্ট্রোলার? .প্রিসেন্টিংভিউ কনট্রোলার? উপস্থাপন)।
এলি বার্ক


3

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

DEViewController.h ফাইল:

#import <UIKit/UIKit.h>

// it is a base class for all view controllers within a project
@interface DEViewController : UIViewController 

// specify a way viewcontroller, is presented  by another viewcontroller
// the presented view controller should manually assign the value to it
typedef NS_ENUM(NSUInteger, SSViewControllerPresentationMethod) {
    SSViewControllerPresentationMethodUnspecified = 0,
    SSViewControllerPresentationMethodPush,
    SSViewControllerPresentationMethodModal,
};
@property (nonatomic) SSViewControllerPresentationMethod viewControllerPresentationMethod;

// other properties/methods...
@end

উপস্থাপনাগুলি এখন এইভাবে পরিচালনা করা যেতে পারে:

নেভিগেশন স্ট্যাকের দিকে ঠেলা:

// DETestViewController inherits from DEViewController
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodPush;
[self.navigationController pushViewController:vc animated:YES];

পরিভ্রমন সহ মডেল উপস্থাপন:

DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
UINavigationController *nav = [[UINavigationController alloc]
                               initWithRootViewController:vc];
[self presentViewController:nav animated:YES completion:nil];

মোডলি উপস্থাপন:

DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
[self presentViewController:vc animated:YES completion:nil];

এছাড়াও, DEViewControllerআমরা উল্লিখিত সম্পত্তিটির সমান হলে "পরীক্ষা করে" ফ্যালব্যাক যোগ করতে পারি SSViewControllerPresentationMethodUnspecified:

- (BOOL)isViewControllerPushed
{
    if (self.viewControllerPresentationMethod != SSViewControllerPresentationMethodUnspecified) {
        return (BOOL)(self.viewControllerPresentationMethod == SSViewControllerPresentationMethodPush);
    }

    else {
        // fallback to default determination method
        return (BOOL)self.navigationController.viewControllers.count > 1;
    }
}

3

ধরে নিই যে আপনি যে সমস্ত ভিউ কন্ট্রোলারগুলি মোডালি উপস্থাপন করেছেন তারা একটি নতুন নেভিগেশন কন্ট্রোলারের (যা আপনার সর্বদা করা উচিত) ভিতরে আবৃত থাকে, আপনি এই সম্পত্তিটি আপনার ভিসিতে যুক্ত করতে পারেন।

private var wasPushed: Bool {
    guard let vc = navigationController?.viewControllers.first where vc == self else {
        return true
    }

    return false
}

1
যা আপনার সর্বদা করা উচিত - কেন দয়া করে ব্যাখ্যা করুন?
আলেকজান্ডার আবাকুমভ

আলেকজান্ডার, আপনার উচিত হবে না।
নিকডনক

2

আপনার নিয়ামকটিকে ধাক্কা দেওয়া হয় বা আপনি যে কোনও জায়গায় কেবল কোডের নীচে ব্যবহার করবেন না তা সনাক্ত করতে:

if ([[[self.parentViewController childViewControllers] firstObject] isKindOfClass:[self class]]) {

    // Not pushed
}
else {

    // Pushed
}

আমি আশা করি এই কোডটি যে কাউকে সহায়তা করতে পারে ...


1
আপনি একাধিক স্থানে একই ভিউ কন্ট্রোলার ক্লাস ব্যবহার করার সময় এই পদ্ধতিটি কার্যকর হয় না, কারণ এটি কেবলমাত্র এর ক্লাসটি পরীক্ষা করে। পরিবর্তে আপনি স্পষ্টভাবে সাম্য পরীক্ষা করতে পারেন।
gklka

1

self.navigationController != nil এর অর্থ এটি একটি নেভিগেশন স্ট্যাকের মধ্যে রয়েছে।


25
এখনও একটি
মডেল

সুতরাং 'মডেল' এবং 'নেভিগেশন স্ট্যাকের উপর চাপ দেওয়া' পারস্পরিক একচেটিয়া নয়। এটি চিন্তাভাবনা প্রসঙ্গে নির্ভর করে তবে স্ব.নিভিশনকন্ট্রোলার নিল নয় কিনা তা যাচাই করা কোনও নেভিগেশন নিয়ন্ত্রকের একটি ভিউ কন্ট্রোলার কিনা তা উত্তর দেয় না।
ড্যানিয়েল

@ ড্যানিয়েল পার্থক্যটি "ধাক্কা" এবং "উপস্থাপিত" এর মধ্যে রয়েছে। "মডেল" এর সাথে কোনও সম্পর্ক নেই I আমি বিশ্বাস করি "কোল্ডলজিক" বলতে "উপস্থাপিত" হয়েছিল যখন তারা "মোডাল" বলেছিলেন
রামডি

1
if let navigationController = self.navigationController, navigationController.isBeingPresented {
    // being presented
}else{
    // being pushed
}

0

আপনি যদি আইওএস 5.0 বা তার চেয়ে বেশি পরে ব্যবহার করেন তবে দয়া করে এই কোডটি ব্যবহার করুন

-(BOOL)isPresented
{
    if ([self isBeingPresented]) {
        // being presented
         return YES;
    } else if ([self isMovingToParentViewController]) {
        // being pushed
         return NO;
    } else {
        // simply showing again because another VC was dismissed
         return NO;
    }
}

0

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

extension UIViewController {
    /**
      returns true only if the viewcontroller is presented.
    */
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            if let parent = parent, !(parent is UINavigationController || parent is UITabBarController) {
                return false
            }
            return true
        } else if let navController = navigationController, navController.presentingViewController?.presentedViewController == navController {
            return true
        } else if tabBarController?.presentingViewController is UITabBarController {
            return true
        }
        return false
    }
}

জোনাজের উত্তরটির জন্য ধন্যবাদ । আবার আরও অনুকূলিতকরণের জন্য জায়গা রয়েছে space মন্তব্য বিভাগে হ্যান্ডেল করা প্রয়োজন যে মামলা সম্পর্কে দয়া করে আলোচনা করুন।


-1

কারও জন্য যারা ভাবছেন, ভিউকন্ট্রোলারকে কীভাবে এটি উপস্থাপন করা হচ্ছে তা বলবেন

যদি Aউপস্থাপন করা / ঠেলাঠেলি করা হয়B

  1. একটি enumএবং propertyইন সংজ্ঞা দিনB

    enum ViewPresentationStyle {
        case Push
        case Present
    }
    
    //and write property 
    
    var vcPresentationStyle : ViewPresentationStyle = .Push //default value, considering that B is pushed 
  2. এখন Aনিয়ামক দর্শনার্থে, Bবরাদ্দ করে এটি উপস্থাপন করা / চালিত হচ্ছে কিনা তা বলুনpresentationStyle

    func presentBViewController() {
        let bViewController = B()
        bViewController.vcPresentationStyle = .Present //telling B that it is being presented
        self.presentViewController(bViewController, animated: true, completion: nil)
    }
  3. Bভিউ কন্ট্রোলারে ব্যবহার

    override func viewDidLoad() {
        super.viewDidLoad()
    
        if self.vcPresentationStyle == .Present {
            //is being presented 
        }
        else {
            //is being pushed
        }
    
    }

-2
id presentedController = self.navigationController.modalViewController;
if (presentedController) {
     // Some view is Presented
} else {
     // Some view is Pushed
}

ভিউকন্ট্রোলার উপস্থাপন করা বা ধাক্কা দেওয়া হলে এটি আপনাকে জানাবে


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