viewWillDisappear:تحديد ما إذا كان عرض وحدة تحكم يتم برزت أو يظهر الفرعية تحكم عرض
-
08-07-2019 - |
سؤال
أنا تكافح من أجل إيجاد حل جيد لهذه المشكلة.في عرض المراقب المالي -viewWillDisappear:
طريقة, أنا بحاجة إلى إيجاد طريقة لتحديد ما إذا كان ذلك بسبب عرض وحدة تحكم يتم دفعها على وحدة تحكم الملاحة المكدس ، أو ما إذا كان عرض وحدة تحكم تختفي لأنه قد برزت.
في هذه اللحظة أنا وضع الأعلام مثل isShowingChildViewController
ولكن الأمر يزداد معقدة إلى حد ما.الطريقة الوحيدة أعتقد أنني يمكن الكشف عن ذلك في -dealloc
الأسلوب.
المحلول
ويمكنك استخدام ما يلي.
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
// View is disappearing because a new view controller was pushed onto the stack
NSLog(@"New view controller was pushed");
} else if ([viewControllers indexOfObject:self] == NSNotFound) {
// View is disappearing because it was popped from the stack
NSLog(@"View controller was popped");
}
}
وهذا هو، بطبيعة الحال، ممكن لأن كومة رأي تحكم في UINavigationController في (يتعرض من خلال الخاصية viewControllers) تم تحديث في الوقت الذي يسمى viewWillDisappear.
نصائح أخرى
وأعتقد أن أسهل طريقة هي:
- (void)viewWillDisappear:(BOOL)animated
{
if ([self isMovingFromParentViewController])
{
NSLog(@"View controller was popped");
}
else
{
NSLog(@"New view controller was pushed");
}
[super viewWillDisappear:animated];
}
وسويفت:
override func viewWillDisappear(animated: Bool)
{
if isMovingFromParentViewController
{
print("View controller was popped")
}
else
{
print("New view controller was pushed")
}
super.viewWillDisappear(animated)
}
ومن الوثائق أبل في UIViewController.h:
<اقتباس فقرة>و"هذه الطرق الأربعة يمكن استخدامها في مظهر وحدة تحكم طريقة العرض الاسترجاعات لتحديد ما إذا كان يتم تقديمه، رفض، أو إضافتها أو إزالة وحدة تحكم رأي الطفل. على سبيل المثال، وحدة تحكم الرأي يمكن معرفة ما اذا كان يختفي لأنه تم صرف النظر عنه أو برزت عن طريق طرح نفسها في viewWillDisappear لها: طريقة عن طريق فحص التعبير ([النفس isBeingDismissed] || [النفس isMovingFromParentViewController]). "
و- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);
و- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);
و- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);
و- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);
وهكذا نعم، والطريقة الوحيدة الموثقة للقيام بذلك هي على النحو التالي:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if ([self isBeingDismissed] || [self isMovingFromParentViewController]) {
}
}
وسويفت 3 النسخة:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if self.isBeingDismissed || self.isMovingFromParentViewController {
}
}
إذا كنت ترغب فقط في معرفة ما إذا كانت وجهة نظركم هو الحصول على انتشرت، لقد اكتشفت للتو أن self.navigationController
هو nil
في viewDidDisappear
، عندما يتم إزالته من كومة من أجهزة التحكم. ذلك أن اختبار بديل بسيط.
و(هذا اكتشفت بعد محاولة كل أنواع من التشويهات الأخرى. أنا مندهش ليس هناك بروتوكول تحكم التنقل للتسجيل تحكم بغية أن يخطر على الملوثات العضوية الثابتة. لا يمكنك استخدام UINavigationControllerDelegate
لأن هذا الواقع لا عمل عرض حقيقي).
وسويفت 4
override func viewWillDisappear(_ animated: Bool)
{
super.viewWillDisappear(animated)
if self.isMovingFromParent
{
//View Controller Popped
}
else
{
//New view controller pushed
}
}
في سويفت:
override func viewWillDisappear(animated: Bool) {
if let navigationController = self.navigationController {
if !contains(navigationController.viewControllers as! Array<UIViewController>, self) {
}
}
super.viewWillDisappear(animated)
}
وأنا العثور على وثائق أبل على هذا من الصعب أن نفهم. هذا التمديد يساعد على معرفة الدول في كل التنقل.
extension UIViewController {
public func printTransitionStates() {
print("isBeingPresented=\(isBeingPresented)")
print("isBeingDismissed=\(isBeingDismissed)")
print("isMovingToParentViewController=\(isMovingToParentViewController)")
print("isMovingFromParentViewController=\(isMovingFromParentViewController)")
}
}
وهذه مسألة قديمة نوعا ما ولكن رأيت ذلك عن طريق الصدفة لذلك أريد للنشر أفضل الممارسات (AFAIK)
ويمكنك القيام به فقط
if([self.navigationController.viewControllers indexOfObject:self]==NSNotFound)
// view controller popped
}
وهذا ينطبق على على iOS7 ، أو أي فكرة إذا كان ينطبق على أي منها الأخرى. من ما أعرفه، في viewDidDisappear
وجهة نظر بالفعل تم برزت. وهو ما يعني عند الاستعلام self.navigationController.viewControllers
ستحصل على nil
. حتى مجرد معرفة ما اذا كان هذا هو لا شيء.
وTL، DR
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
if (self.navigationController.viewControllers == nil) {
// It has been popped!
NSLog(@"Popped and Gone");
}
}
وsegues على أن يكون وسيلة فعالة جدا لمعالجة هذه المشكلة في دائرة الرقابة الداخلية 6+. إذا كنت قد أعطيت للسغ] معين معرف في واجهة باني يمكنك التحقق من ذلك في prepareForSegue
.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"LoginSegue"]) {
NSLog(@"Push");
// Do something specific here, or set a BOOL indicating
// a push has occurred that will be checked later
}
}
وأفترض أنك يعني أن وجهة نظركم يتم نقلها أسفل كومة وحدة تحكم الملاحة من قبل دفع طريقة عرض جديدة عندما تقول دفعت إلى المكدس. أود أن أقترح باستخدام طريقة viewDidUnload
لإضافة بيان NSLog
أن أكتب شيئا إلى وحدة حتى تتمكن من معرفة ما يجري، قد ترغب في إضافة NSLog
إلى viewWillDissappeer
.
هنا هو فئة لإنجاز نفس الشيء sbrocket الجواب:
الرأس:
#import <UIKit/UIKit.h>
@interface UIViewController (isBeingPopped)
- (BOOL) isBeingPopped;
@end
المصدر:
#import "UIViewController+isBeingPopped.h"
@implementation UIViewController (isBeingPopped)
- (BOOL) isBeingPopped {
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
return NO;
} else if ([viewControllers indexOfObject:self] == NSNotFound) {
return YES;
}
return NO;
}
@end