我想要一个具有透明背景色的模态视图,以便用户可以看到它后面的 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。
有几个限制:
- 你必须呈现给最 Root View Controller ,所以如果你想 覆盖整个屏幕,你就有了一个 VC UINavigationController,将其呈现给导航 Controller 。
- 可能是旧版 iOS 上的一些旋转问题(我没看到) 构建(4.0 左右)
- 目前仅处理 Cross Dissolve 和 Cover Vertical 动画。
关于objective-c - 如何在 Objective-C 中将模态背景颜色更改为透明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4537624/