objective-c - 如何在 Objective-C 中将模态背景颜色更改为透明

标签 objective-c background modal-dialog

我想要一个具有透明背景色的模态视图,以便用户可以看到它后面的 View 。

最佳答案

好的,所以 presentModalViewController 不提供这种行为......但是它仍然是可能的。我创建了一个适合我(希望你)的类别。作为一个额外的好处,它还可以防止与同时关闭和呈现模态视图相关的崩溃!

头文件:

//
//  UIViewController+overView.h
//  Created by Kevin Lohman on 5/30/12.
//

#import <UIKit/UIKit.h>

@interface UIViewController (OverView)
- (void)presentOverViewController:(UIViewController *)modalViewController animated:(BOOL)animated;
- (void)dismissOverViewControllerAnimated:(BOOL)animated;
@end

执行文件:

//
//  UIViewController+overView.m
//  Created by Kevin Lohman on 5/30/12.
//

#import "UIViewController+overView.h"

@implementation UIViewController (OverView)

#define kUIViewControllerOverViewDismissNotification @"OverViewDismissNotification"

const float kUIViewControllerOverViewAnimationDuration = 0.75;
const NSInteger kUIViewControllerOverViewTag = 8008135; // Arbitrary number, so as not to conflict
- (void)overViewDismissed
{
    [self autorelease];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kUIViewControllerOverViewDismissNotification object:self.view];
}

- (void)presentOverViewController:(UIViewController *)modalViewController animated:(BOOL)animated
{
    UIView *toView = self.view;

    CGRect finalRect = CGRectIntersection([[UIScreen mainScreen] applicationFrame], self.view.frame); // Make sure it doesn't go under menu bar
    modalViewController.view.frame = finalRect;
    modalViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
    modalViewController.view.tag = kUIViewControllerOverViewTag+modalViewController.modalTransitionStyle; // Hiding some info here :)

    if(animated)
    {
        switch(modalViewController.modalTransitionStyle)
        {
            // Currently only cross dissolve and cover vertical supported... if you add support let me know.
            case UIModalTransitionStyleCrossDissolve:
            {
                float beforeAlpha = modalViewController.view.alpha;
                modalViewController.view.alpha = 0;
                [toView addSubview:modalViewController.view];
                [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{
                    modalViewController.view.alpha = beforeAlpha;
                }];
                break;
            }
            case UIModalTransitionStyleCoverVertical:
            default:
            {
                modalViewController.view.frame = CGRectMake(modalViewController.view.frame.origin.x, modalViewController.view.frame.size.height, 
                                                            modalViewController.view.frame.size.width, modalViewController.view.frame.size.height);
                [toView addSubview:modalViewController.view];
                [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{
                    modalViewController.view.frame = finalRect;
                }];
                break;
            }
        }
    }
    else {
        [toView addSubview:modalViewController.view];
    }

    [modalViewController retain]; // Keep it around until we dismiss it.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(overViewDismissed) name:kUIViewControllerOverViewDismissNotification object:modalViewController.view]; // Release will happen when this notification is posted
}

NSInteger transitionStyleForTag(tag)
{
    if (tag >= kUIViewControllerOverViewTag && tag <= kUIViewControllerOverViewTag+UIModalTransitionStylePartialCurl)
    {
        return tag-kUIViewControllerOverViewTag;
    }
    else {
        return -1; // Not a Over View
    }
}

- (void)dismissOverViewControllerAnimated:(BOOL)animated
{
    UIView *overView = transitionStyleForTag(self.view.tag) >= 0 ? self.view : nil; // Can dismiss ourselves
    for(UIView *subview in self.view.subviews)
    {
        if(transitionStyleForTag(subview.tag) >= 0)
            overView = subview; // Keep going, lets dismiss last presented first
    }
    if(!overView) return; // None to dismiss

    if(animated)
    {
        switch(transitionStyleForTag(overView.tag))
        {
            // Currently only cross dissolve and cover vertical supported... if you add support let me know.
            case UIModalTransitionStyleCrossDissolve:
            {
                float beforeAlpha = overView.alpha;
                [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{
                    overView.alpha = 0;
                } completion:^(BOOL finished) {
                    [overView removeFromSuperview];
                    overView.alpha = beforeAlpha;
                    [[NSNotificationCenter defaultCenter] postNotificationName:kUIViewControllerOverViewDismissNotification object:overView];
                }];
                break;
            }
            case UIModalTransitionStyleCoverVertical:
            default:
            {
                [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{
                    overView.frame = CGRectMake(0, overView.frame.size.height, overView.frame.size.width, overView.frame.size.height);
                } completion:^(BOOL finished) {
                    [overView removeFromSuperview];
                    [[NSNotificationCenter defaultCenter] postNotificationName:kUIViewControllerOverViewDismissNotification object:overView];
                }];
                break;
            }
        }
    }
    else {
        [overView removeFromSuperview];
        [[NSNotificationCenter defaultCenter] postNotificationName:kUIViewControllerOverViewDismissNotification object:overView];
    }
}
@end

然后要使用它,只需使用 presentOverViewController 代替 presentModalViewController 并使用 dismissOverViewController 代替 dissmissModalViewController。

有几个限制:

  1. 你必须呈现给最 Root View Controller ,所以如果你想 覆盖整个屏幕,你就有了一个 VC UINavigationController,将其呈现给导航 Controller 。
  2. 可能是旧版 iOS 上的一些旋转问题(我没看到) 构建(4.0 左右)
  3. 目前仅处理 Cross Dissolve 和 Cover Vertical 动画。

关于objective-c - 如何在 Objective-C 中将模态背景颜色更改为透明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4537624/

相关文章:

iphone - 另一个 Xcode 项目中的 undefined symbol

objective-c - 适用于所有通用尺寸 iPhone 的 ImageView

html - 如何使html中的图像透明?

iphone - 测试应用程序是否确实从 UILocalNotification 变为事件状态

Java SWT - 缩放背景图像在编译后不起作用

ios - 将消息从父 View Controller 发送到容器 View

javascript - 一旦出现,如何在 Bootstrap 模式中为特定字段设置焦点

javascript - 单击链接无法打开模态框

twitter-bootstrap - 如何从 Bootstrap 模态形式获取值以在 MVC Controller 中使用

ios - 如何根据主数组中的长度对数组进行排序