Как изменить модальный цвет фона на прозрачный в Objective-C
Я хотел бы иметь модальный вид с прозрачным цветом фона, чтобы вид за ним мог быть виден пользователем.
5 ответов
хорошо, поэтому 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.
есть несколько ограничений:
- вы должны представить контроллеру корневого большинства представлений, поэтому, если вы хотите чтобы покрыть весь экран, и у вас есть VC внутри UINavigationController, представьте его навигационному контроллеру.
- могут быть некоторые проблемы с ротацией (я не видел) на старой iOS сборки (4.0 или около того)
- в настоящее время только ручки крест растворяют и обложка вертикальной анимации.
ответ для меня был одной строкой кода, добавленной в контроллер родительского вида перед представлением контроллера модального вида:
self.modalPresentationStyle = UIModalPresentationCurrentContext;
это остановит удаление родительского представления после добавления модального представления.
Вероятно, вы хотите добавить UIView в качестве наложения на текущий вид, но сделать это полноэкранным с прозрачным или полупрозрачным фоном. См. первый ответ на этот вопрос:
вам нужно работать в обратном направлении, вроде. Загрузите свой модальный вид, затем добавьте все свои элементы на него "вручную" в качестве подвида, таким образом, они не будут скрыты. Да, это много кодирования, но это можно сделать. Я сделал это для воспроизведения фильмов и дополнительных элементов на экране, установив меньший размер кадра для проигрывателя фильмов и бросив несколько кнопок и textviews вокруг него в качестве подвидов. Б