[iphone] هل من الممكن تحديد ما إذا كان يتم تقديم ViewController كموديل؟



Answers

إذا كنت تبحث عن iOS 6+ ، فسيتم إهمال هذه الإجابة ويجب عليك التحقق من إجابة Gabriele Petronella

لا توجد طريقة مرتبة للقيام بذلك ، كخاصية أو أسلوب الأصلي إلى UIKit. ما يمكنك القيام به هو التحقق من العديد من جوانب وحدة التحكم الخاصة بك لضمان تقديمها على أنها مشروطة.

لذلك ، للتحقق مما إذا كان يتم تقديم وحدة التحكم الحالية (مثل self in the bello) بطريقة مشروطة أم لا ، لدي الوظيفة التالية إما في فئة UIViewController ، أو (إذا كان مشروعك لا يحتاج إلى استخدام وحدات التحكم الأخرى في UIKit ، مثل UITableViewController على سبيل المثال) في وحدة تحكم أساسية UITableViewController وحدات التحكم الأخرى الخاصة بي

-(BOOL)isModal {

     BOOL isModal = ((self.parentViewController && self.parentViewController.modalViewController == self) || 
            //or if I have a navigation controller, check if its parent modal view controller is self navigation controller
            ( self.navigationController && self.navigationController.parentViewController && self.navigationController.parentViewController.modalViewController == self.navigationController) || 
            //or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation
            [[[self tabBarController] parentViewController] isKindOfClass:[UITabBarController class]]);

    //iOS 5+
    if (!isModal && [self respondsToSelector:@selector(presentingViewController)]) {

        isModal = ((self.presentingViewController && self.presentingViewController.modalViewController == self) || 
             //or if I have a navigation controller, check if its parent modal view controller is self navigation controller
             (self.navigationController && self.navigationController.presentingViewController && self.navigationController.presentingViewController.modalViewController == self.navigationController) || 
             //or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation
             [[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]]);

    }

    return isModal;        

}

تحرير: أضفت آخر فحص لمعرفة ما إذا كان UITabBarController قيد الاستخدام ، وقمت بتقديم UITabBarController آخر كهيئة مشروطة.

EDIT 2: تمت إضافة فحص iOS 5+ ، حيث لم يعد parentViewController يجيب عن parentViewController بعد الآن ، ولكن presentingViewController parentViewController بدلاً من ذلك.

تحرير 3: لقد قمت بإنشاء gist فقط في حالة https://gist.github.com/3174081

Question

هل من الممكن التحقق داخل فئة ViewController التي يتم تقديمها كوحدة تحكم عرض مشروط؟




هنا هو بلدي نسخة معدلة من isModal @ GabrielePetronella ، والذي يعمل مع وحدات تحكم العرض الواردة في أنه يسير التسلسل الهرمي parentViewController أولا. سحبت أيضًا الشفرة إلى عدة أسطر ، لذلك من الواضح ما الذي تفعله.

var isModal: Bool {
    // If we are a child view controller, we need to check our parent's presentation
    // rather than our own.  So walk up the chain until we don't see any parentViewControllers
    var potentiallyPresentedViewController : UIViewController = self
    while (potentiallyPresentedViewController.parentViewController != nil) {
        potentiallyPresentedViewController = potentiallyPresentedViewController.parentViewController!
    }

    if self.presentingViewController?.presentedViewController == potentiallyPresentedViewController {
        return true
    }

    if let navigationController = potentiallyPresentedViewController.navigationController {
        if navigationController.presentingViewController?.presentedViewController == navigationController {
            return true
        }
    }

    return potentiallyPresentedViewController.tabBarController?.presentingViewController is UITabBarController
}



ما نجح لي هو ما يلي:

// this is the trick: set parent view controller as application's window root view controller
UIApplication.sharedApplication.delegate.window.rootViewController = viewController;

// assert no modal view is presented
XCTAssertNil(viewController.presentedViewController);

// simulate button tap which shows modal view controller
[viewController.deleteButton sendActionsForControlEvents:UIControlEventTouchUpInside];

// assert that modal view controller is presented
XCTAssertEqualObjects(viewController.presentedViewController.class, MyModalViewController.class);

بقدر ما اختبرت ، وهذا يعمل ل iOS7 و iOS8. لم حاول على iOS6 ومع ذلك.




هذا يجب أن يعمل.

if(self.parentViewController.modalViewController == self)…



إذا لم يكن هناك ، يمكنك تعريف خاصية لهذا (providedAsModal) في الفئة الفرعية UIViewController وتعيينها إلى YES قبل تقديم ViewController كطريقة عرض مشروطة.

childVC.presentedAsModal = YES;
[parentVC presentModalViewController:childVC animated:YES];

يمكنك التحقق من هذه القيمة في العرض الخاص بك viewWillAppear override.

أعتقد أنه لا توجد خاصية رسمية تنص على كيفية عرض الرأي ، ولكن لا شيء يمنعك من إنشاء العرض الخاص بك.




في مشروعي لدي وحدة تحكم في العرض (تفصيل) يمكن تقديمها إما بشكل مشروط (عند إضافة عنصر جديد) أو بالدفع (عند تحرير عنصر موجود) بواسطة وحدة التحكم في العرض الرئيسي. عندما ينقر المستخدم على [Done] ، تستدعي أداة التحكم في العرض التفصيلي طريقة وحدة التحكم في العرض الرئيسي لإعلامه بأنه جاهز للإغلاق. يجب على Master تحديد كيفية عرض Detail من أجل معرفة كيفية إغلاقه. هكذا أفعل هذا:

UIViewController *vc = self.navigationController.viewControllers.lastObject;
if (vc == self) {
    [self dismissViewControllerAnimated:YES completion:NULL];
} else {
    [self.navigationController popViewControllerAnimated:YES];
}



إذا لم تكن بحاجة إلى التمييز بين طرق عرض ملء الشاشة وطرق غير مشروطة ، وهذا هو الحال في مشروعي (كنت أتعامل مع مشكلة تحدث فقط مع أوراق النماذج وأوراق الصفحة) ، يمكنك استخدام modalPresentationStyle خاصية UIViewController:

switch (self.modalPresentationStyle) {
    case 0: NSLog(@"full screen, or not modal"); break;
    case 1: NSLog(@"page sheet"); break;
    case 2: NSLog(@"form sheet"); break;
}



Links