ios - permission - iphone bottom bar




iOS:具有透明背景的Modal ViewController (15)

我試圖以透明背景的形式呈現視圖控制器。 我的目標是讓呈現和呈現的視圖控制器的視圖同時顯示。 問題是,當呈現動畫完成時,呈現視圖控制器的視圖消失。

- (IBAction)pushModalViewControllerButtonPressed:(id)sender
{
    ModalViewController *modalVC = [[ModalViewController alloc] init];
    [self presentViewController:modalVC animated:YES completion:nil];
}

我知道我可以將視圖添加為子視圖,但由於某種原因,我想避免此解決方案。 我怎麼修復它?


登錄屏幕是一種模式,這意味著它位於前一屏幕的頂部。 到目前為止,我們擁有模糊背景,但它並沒有模糊任何東西; 它只是一個灰色的背景。

我們需要正確設置我們的Modal。

圖像鏈接目標

  • 首先,我們需要將視圖控制器的視圖背景更改為清除顏色。 這僅僅意味著它應該是透明的。 默認情況下,該視圖是白色的。

  • 其次,我們需要選擇導致Login屏幕的Segue,並在Attribute Inspector中將Presentation設置為Over Current Context。 此選項僅適用於啟用了自動佈局和大小類別的情況。

圖像鏈接目標


回顧這裡的所有好的答案和評論,並在移動到新的ViewController時仍然有一個動畫,這是我做的:(支持iOS 6及更高版本)

如果您使用UINavigationController \ UITabBarController

    SomeViewController *vcThatWillBeDisplayed = [self.storyboard instantiateViewControllerWithIdentifier:@"SomeVC"];

    vcThatWillBeDisplayed.view.backgroundColor = [UIColor colorWithRed: 255/255.0 green:255/255.0 blue:255/255.0 alpha:0.50];    

    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:presentedVC animated:YES completion:NULL];

如果你這樣做,你會失去你的modalTransitionStyle動畫。 為了解決它,你可以很容易的添加到你的SomeViewController類中:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIView animateWithDuration:0.4 animations:^() {self.view.alpha = 1;}
       completion:^(BOOL finished){}];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.alpha = 0;
}

以下代碼僅適用於iPad。

self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalVC animated:YES];

我會去添加一個子視圖。

這是一個非常好的討論。 具體看看評論。 不僅是答案。

模態視圖

如果我是你,我不會這樣做。 我會添加一個子視圖,並做到這一點。 這似乎讓我對事物有更好的控制。

編輯:

正如Paul Linsay所提到的,由於iOS 8需要的是所呈現的ViewController的modalPresentationStyle所需要的是UIModalPresentationOverFullScreen 。 這也會覆蓋navigationBar和tabBar按鈕。


使用swift解決這個問題的答案如下。

let vc = MyViewController()
vc.view.backgroundColor = UIColor.clear // or whatever color.
vc.modalPresentationStyle = .overCurrentContent
present(vc, animated: true, completion: nil)

創建一個segue以模態呈現,並將該segue的Presentation屬性設置為當前上下文,它將工作100%


另一種方法是使用“容器視圖”。 只需將alpha設置為1並嵌入seque。 XCode 5,目標iOS7。 在iPhone上測試。

容器視圖可從iOS6獲得。 Link到博客文章。


在iOS 7和iOS 8上測試的完整方法。

@interface UIViewController (MBOverCurrentContextModalPresenting)

/// @warning Some method of viewControllerToPresent will called twice before iOS 8, e.g. viewWillAppear:.
- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;

@end

@implementation UIViewController (MBOverCurrentContextModalPresenting)

- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    UIViewController *presentingVC = self;

    // iOS 8 before
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
        UIViewController *root = presentingVC;
        while (root.parentViewController) {
            root = root.parentViewController;
        }

        [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
            [viewControllerToPresent dismissViewControllerAnimated:NO completion:^{
                UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = UIModalPresentationCurrentContext;
                }
                [presentingVC presentViewController:viewControllerToPresent animated:NO completion:completion];
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = orginalStyle;
                }
            }];
        }];
        return;
    }

    UIModalPresentationStyle orginalStyle = viewControllerToPresent.modalPresentationStyle;
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    }
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:completion];
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = orginalStyle;
    }
}

@end

在iOS 8.0及以上版本中,可以通過將屬性modalPresentationStyle設置為UIModalPresentationOverCurrentContext

//Set property **definesPresentationContext** YES to avoid presenting over presenting-viewController's navigation bar

self.definesPresentationContext = YES; //self is presenting view controller
presentedController.view.backgroundColor = [YOUR_COLOR with alpha OR clearColor]
presentedController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:presentedController animated:YES completion:nil];


如果您使用的是Storyboard,則可以按照以下步驟操作:

  1. 添加視圖控制器(V2),以您想要的方式設置UI
  • 添加一個UIView - 設置背景黑色和不透明度為0.5
  • 添加另一個UIView(2) - 這將作為你的彈出窗口(請注意,UIView和UIView(2)不能具有相同的級別/層次結構。不要將imageview視圖視圖的子視圖,否則視圖的不透明度會影響UIView(2))
  1. 現在V2 Modally

  2. 點擊繼續。 在屬性檢查器中,將演示文稿設置為全屏 。 如果你喜歡,請移除動畫

  1. 選擇V2。 在屬性檢查器中,將演示文稿設置為全屏 。 檢查定義上下文並提供上下文

  1. 選擇您的V2的MainView(請查看圖片)。 將backgroundColor設置為清除顏色


將導航的modalPresentationStyle設置為UIModalPresentationCustom

並將您呈現的視圖控制器的背景色設置為清晰的顏色。


我創建了一個對象來處理我稱之為“疊加模式”的表示,這意味著它保留了背景的視圖,並允許您使用具有透明背景的模式。

它有一個簡單的方法:

- (void)presentViewController:(UIViewController *)presentedViewController
       fromViewController:(UIViewController *)presentingViewController
{
    presentedViewController.modalPresentationStyle = UIModalPresentationCustom;
    presentedViewController.transitioningDelegate = self;
    presentedViewController.modalPresentationCapturesStatusBarAppearance = YES;

    [presentedViewController setNeedsStatusBarAppearanceUpdate];

    [presentingViewController presentViewController:presentedViewController
                                       animated:YES
                                     completion:nil];
}

如果您呈現的視圖控制器具有不同的preferredStatusBarStyle ,將modalPresentationCapturesStatusBarAppearance屬性設置為YES並強制更新狀態欄外觀很重要。

這個對象應該有一個@property (assign, nonatommic) isPresenting

您希望此對象符合UIViewControllerAnimatedTransitioningUIViewControllerTransitioningDelegate協議並實現以下方法:

- (id)animationControllerForPresentedController:(UIViewController *)presented
                           presentingController:(UIViewController *)presenting
                               sourceController:(UIViewController *)source
{
    self.isPresenting = YES;

    return self;
}

- (id)animationControllerForDismissedController:(UIViewController *)dismissed
{
    self.isPresenting = NO;

    return self;
}

和:

- (NSTimeInterval)transitionDuration:(id)transitionContext
{
    return 0.25;
}

- (void)animateTransition:(id)transitionContext
{
    UIViewController* firstVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController* secondVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView* containerView = [transitionContext containerView];
    UIView* firstView = firstVC.view;
    UIView* secondView = secondVC.view;

    if (self.isPresenting) {
        [containerView addSubview:secondView];
        secondView.frame = (CGRect){
            containerView.frame.origin.x,
            containerView.frame.origin.y + containerView.frame.size.height,
            containerView.frame.size
        };

        firstView.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
        [UIView animateWithDuration:0.25 animations:^{
            secondView.frame = containerView.frame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
        } else {
        [UIView animateWithDuration:0.25 animations:^{
            firstView.frame = (CGRect){
                containerView.frame.origin.x,
                containerView.frame.origin.y + containerView.frame.size.height,
                containerView.frame.size
        };

        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
}

這是一個模仿默認模態動畫的滑動底部動畫,但您可以隨心所欲地製作它。

重要的是呈現視圖控制器的視圖將保留在後面,讓您創建透明效果。

此解決方案適用於iOS 7+


我在呈現的視圖控制器的init方法中添加了這三行,並且像魅力一樣工作:

self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[self setModalPresentationStyle:UIModalPresentationOverCurrentContext];

編輯(在iOS 9.3上工作):

self.modalPresentationStyle = UIModalPresentationOverFullScreen;

根據文件:

UIModalPresentationOverFullScreen呈現視圖覆蓋屏幕的視圖呈現樣式。 演示完成後,呈現內容下的視圖不會從視圖層次結構中刪除。 因此,如果呈現的視圖控制器沒有在屏幕上填充不透明的內容,底層內容就會顯示出來。

適用於iOS 8.0及更高版本。


此代碼在iOS6和iOS7下的iPhone上正常工作:

presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];

在這種情況下,你錯過了滑動動畫。 要保留動畫,您仍然可以使用以下“非優雅”擴展名:

[presentingVC presentViewController:presentedVC animated:YES completion:^{
    [presentedVC dismissViewControllerAnimated:NO completion:^{
        presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
        [presentingVC presentViewController:presentedVC animated:NO completion:NULL];
    }];
}];

如果我們的presentsV位於UINavigationController或UITabbarController的內部,則需要使用該控制器作為呈現VC的操作。

此外,在iOS7中,您可以實施應用UIViewControllerTransitioningDelegate協議的自定義過渡動畫。 當然,在這種情況下,您可以獲得透明背景

@interface ModalViewController : UIViewController <UIViewControllerTransitioningDelegate>

首先,在呈現之前你必須設置modalPresentationStyle

modalViewController.modalPresentationStyle = UIModalPresentationCustom;

然後你必須實現兩個協議方法

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    CustomAnimatedTransitioning *transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = YES;
    return transitioning;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    CustomAnimatedTransitioning * transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = NO;
    return transitioning;
}

最後一件事是在CustomAnimatedTransitioning類中定義自定義轉換

@interface CustomAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic) BOOL presenting;
@end

@implementation CurrentContextTransitionAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext 
{
    return 0.25;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext 
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    if (self.presenting) {
        // custom presenting animation
    }
    else {
        // custom dismissing animation
    }
}

這個類別適用於我(ios 7,8和9)

H文件

@interface UIViewController (navigation)
- (void) presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
@end

M文件

@implementation UIViewController (navigation)
- (void)presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    if(SYSTEM_VERSION_LESS_THAN(@"8.0")) {
        [self presentIOS7TransparentController:viewControllerToPresent withCompletion:completion];

    }else{
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
         [self presentViewController:viewControllerToPresent animated:YES completion:completion];
    }
}
-(void)presentIOS7TransparentController:(UIViewController *)viewControllerToPresent withCompletion:(void(^)(void))completion
{
    UIViewController *presentingVC = self;
    UIViewController *root = self;
    while (root.parentViewController) {
        root = root.parentViewController;
    }
    UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
    root.modalPresentationStyle = UIModalPresentationCurrentContext;
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
        root.modalPresentationStyle = orginalStyle;
    }];
}
@end

適用於iOS 7-10

if #available(iOS 8.0, *) {
    nextVC.modalPresentationStyle = .OverCurrentContext
    self.presentViewController(nextVC, animated: true, completion: nil)
} else {
    // Fallback on earlier version
    self.modalPresentationStyle = .Custom          
    nextVC.modalTransitionStyle = .CrossDissolve            
    self.presentViewController(nextVC, animated: false, completion: nil)
    }
}




presentmodalviewcontroller