뷰 컨트롤러가 모달로 표시되는지 또는 탐색 스택에 푸시되었는지 확인
뷰 컨트롤러 코드에서 다음을 어떻게 구별 할 수 있습니까?
- 모달로 제시
- 탐색 스택에 푸시 됨
둘 다 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];
결정하려고하는 대신 모달 일 때 뷰 컨트롤러에 알려주는 것이 좋습니다.
테스트하지 않고 소금 한 알로 섭취하십시오.
- (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;
}
에서 스위프트 :
// 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
}
}
한 가지 방법을 간과했습니다 : isBeingPresented
.
isBeingPresented
뷰 컨트롤러가 표시되면 true이고 푸시되면 false입니다.
- (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
}
}
self.navigationController! = nil은 탐색 스택에 있음을 의미합니다.
탐색 컨트롤러가 모달로 표시되는 동안 현재 뷰 컨트롤러가 푸시되는 경우를 처리하기 위해 현재 뷰 컨트롤러가 탐색 스택의 루트 컨트롤러인지 확인하는 몇 줄의 코드를 추가했습니다.
extension UIViewController{
func isModal() -> Bool {
if let navigationController = self.navigationController{
if navigationController.viewControllers.first != self{
return false
}
}
if self.presentingViewController != nil {
return true
}
if self.navigationController?.presentingViewController?.presentedViewController == self.navigationController {
return true
}
if self.tabBarController?.presentingViewController is UITabBarController {
return true
}
return false
}
}
Swift 3
다음은 푸시 된 경우 isModal()
반환 이 제시된 스택 에 있을 때 이전 답변에서 언급 된 문제를 해결하는 솔루션입니다 .true
UIViewController
UINavigationController
extension UIViewController {
var isModal: Bool {
if let index = navigationController?.viewControllers.index(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
}
}
}
지금까지 나를 위해 작동합니다. 일부 최적화가 있으면 공유하십시오.
스위프트 4
var isModal: Bool {
return presentingViewController != nil ||
navigationController?.presentingViewController?.presentedViewController === navigationController ||
tabBarController?.presentingViewController is UITabBarController
}
As many folks here suggest, that "checking" methods don't work well for all cases, in my project I've come up with solution to manage that manually. The point is, we usually manage presentation on our own - this is not what happens behind the scene and we must to introspect.
DEViewController.h
file:
#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
The presentations now could be managed this way:
pushed on navigation stack:
// DETestViewController inherits from DEViewController
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodPush;
[self.navigationController pushViewController:vc animated:YES];
presented modally with navigation:
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
UINavigationController *nav = [[UINavigationController alloc]
initWithRootViewController:vc];
[self presentViewController:nav animated:YES completion:nil];
presented modally:
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
[self presentViewController:vc animated:YES completion:nil];
Also, in DEViewController
we could add a fallback to "checking" if the aforementioned property equals to 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;
}
}
Assuming that all viewControllers that you present modally are wrapped inside a new navigationController (which you should always do anyway), you can add this property to your VC.
private var wasPushed: Bool {
guard let vc = navigationController?.viewControllers.first where vc == self else {
return true
}
return false
}
self.navigationController != nil
would mean it's in a navigation stack.
To detect your controller is pushed or not just use below code in anywhere you want:
if ([[[self.parentViewController childViewControllers] firstObject] isKindOfClass:[self class]]) {
// Not pushed
}
else {
// Pushed
}
I hope this code can help anyone...
if let navigationController = self.navigationController, navigationController.isBeingPresented {
// being presented
}else{
// being pushed
}
If you are using ios 5.0 or later than please use this code
-(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;
}
}
if navigationController.presentingViewController != nil {
// Navigation controller is being presented modally
}
id presentedController = self.navigationController.modalViewController;
if (presentedController) {
// Some view is Presented
} else {
// Some view is Pushed
}
This will let you know if viewController is presented or pushed
For some one who's wondering, How to tell ViewController that it is being presented
if A
is presenting/pushing B
Define an
enum
andproperty
inB
enum ViewPresentationStyle { case Push case Present } //and write property var vcPresentationStyle : ViewPresentationStyle = .Push //default value, considering that B is pushed
Now in
A
view controller, tellB
if it is being presented/pushed by assigningpresentationStyle
func presentBViewController() { let bViewController = B() bViewController.vcPresentationStyle = .Present //telling B that it is being presented self.presentViewController(bViewController, animated: true, completion: nil) }
Usage in
B
View Controlleroverride func viewDidLoad() { super.viewDidLoad() if self.vcPresentationStyle == .Present { //is being presented } else { //is being pushed } }
'program tip' 카테고리의 다른 글
GCD의 동시 대기열과 직렬 대기열 (0) | 2020.08.17 |
---|---|
키보드가 나타날 때 UIScrollView를 어떻게 스크롤합니까? (0) | 2020.08.17 |
Task Runner Explorer에서 작업을로드 할 수 없습니다. (0) | 2020.08.17 |
하나의 규칙 내에서 여러 클래스가있는 대상 요소 (0) | 2020.08.17 |
Eclipse에서 선택한 단어의 모든 발생을 강조 표시 할 수 없습니다. (0) | 2020.08.17 |