IPad нестандартного размера контроллера модального просмотра
У меня есть несколько модальных контроллеров вида определенного размера. Я стараюсь избегать использования пользовательских представлений (создание полноэкранного прозрачного полупрозрачного наложения по текущему виду, добавление модального представления по этому представлению, анимация и т.д.), Чтобы представить его, потому что нет модальногоPresentationStyle, который соответствует размеру моего контроллеры.
Теперь я использую UIModalPresentationPageSheet, но мой вид меньше по высоте, и у меня есть уродливое пустое пространство
Желаемая презентация
_______________
| _______ |
| | | |
| | MyVC | |
| | | |
| ------- |
---------------
Фактическое представление
_______________
| | | |
| | MyVC | |
| | | |
| |-------| |
| | blank | |
---------------
Если я использую UIModalPresentationFormSheet, контейнер меньше по ширине.
Я пытаюсь понять, как это сделать, но я не знаю, возможно ли это. Каково решение проблемы представления модального VC, меньшего, чем любой из представленийStyles? Единственное решение состоит в том, чтобы организовать "механизм управления пользовательским модальным представлением"? Popovers не соответствует моим требованиям к дизайну: (
Ответы
Ответ 1
Как и некоторые другие пользователи, у меня также возникла проблема, что происхождение контроллера модального представления было неправильным. После некоторых экспериментов я нашел решение, которое сработало для меня:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.view.superview.bounds = CGRectMake(0, 0, <width>, <height>);
}
Ответ 2
Я получил следующий результат (текст ссылки) с помощью:
self.modalPresentationStyle = UIModalPresentationFormSheet;
и представляя его как контроллер модального представления. Дайте мне знать, если вам нужна дополнительная помощь.
Ответ 3
Все эти ответы не будут работать на SDK ios8.
Это будет работать:
AboutViewController * _aboutViewController = [[AboutViewController alloc] init];
_aboutViewController.modalPresentationStyle = UIModalPresentationFormSheet;
if(IS_IOS8)
{
_aboutViewController.preferredContentSize = CGSizeMake(300, 300);
}
[self presentViewController:_aboutViewController animated:YES completion:nil];
В AboutViewController.m
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
if(!IS_IOS8)
{
self.view.superview.bounds = CGRectMake(0, 0, 300, 300);
}
}
IS_IOS8
#define IS_IOS8 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8)
В iOS 8 вы также можете использовать UIPresentationController, который дает вам больше настроек.
Ответ 4
У меня возникла проблема с настройкой нестандартного размера модала до тех пор, пока я не выясню, для чего был установлен ViewController.view.superview.frame
. Он определяется на основе типа UIModalPresentation. superview.center
даже не требуется (насколько показывает мое тестирование).
Кроме того, я динамически устанавливаю координаты с помощью [UIScreen mainScreen].applicationFrame
, поддерживая только ориентацию ландшафта. Вы должны выполнить условную проверку, чтобы поддерживать как портрет, так и пейзаж, переворачивая значения X/Y и Height/Width.
Вот мое первое рабочее решение для iOS 6.0:
ViewController.modalPresentationStyle = UIModalPresentationFormSheet;
ViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:ViewController animated:YES completion:nil];
ViewController.view.superview.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
ViewController.view.superview.frame = CGRectMake(
// Calcuation based on landscape orientation (width=height)
([UIScreen mainScreen].applicationFrame.size.height/2)-(320/2),// X
([UIScreen mainScreen].applicationFrame.size.width/2)-(320/2),// Y
320,// Width
320// Height
);
И затем я посмотрел на предыдущий ответ и посмотрел на него. Сокращает мое решение, заменяя последнюю строку:
ViewController.view.superview.bounds = CGRectMake(0, 0, 320, 320);
EDIT для окончательного решения и замечаний.
Ответ 5
Лучший способ сделать это - изменить свойство bounds в представлении представления, представленного внутри листа. Когда вы представляете представление по-разному, представленный вид встроен в другое представление.
Вы должны установить свойство bounds супервизора на тот же прямоугольник, что и границы представления. Сначала добавьте личный ivar в свой класс:
@implementation MySpecialFormsheet {
CGRect _realBounds;
}
Лучше всего сделать это в viewWillAppear:
. Добавьте следующий код к контроллеру представления, который представляется модально:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.view.superview.bounds = _realBounds;
}
Вам нужно кэшировать _realBounds
в методе viewDidLoad
:
- (void)viewDidLoad {
_realBounds = self.view.bounds;
[super viewDidLoad];
}
Ответ 6
Это мое решение для просмотра автозапуска НЕ (никогда не пробовали с автозапуском) и совместимы с iOS 7 и iOS 8.
Сначала обязательно вызовите модальное представление следующим образом:
CloudSettingsViewController *cloudController = [[CloudSettingsViewController alloc] initWithNibName:@"CloudSettingsView" bundle:nil];
CGRect originalBounds = cloudController.view.bounds;
cloudController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
cloudController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:cloudController animated:YES completion:nil];
С iOS 8 установите preferredContentSize в методе viewDidLoad модального представления.
- (void)viewDidLoad {
[super viewDidLoad];
// backup of the original size (selected in interface builder)
height = self.view.frame.size.height;
width = self.view.frame.size.width;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) // versioni successive ios 8
self.preferredContentSize = CGSizeMake(width, height); // this is necessary to get the correct size of the modal view
}
Это работает ТАКЖЕ, когда модальное представление должно отображать клавиатуру на iPad.
С предыдущими версиями iOS 8 вы должны установить границы после вызова currentViewController:
[currentController presentViewController:controlPanelController animated:YES completion:nil];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8)
cloudController.view.superview.bounds = originalBounds;//it important to do this after
Ответ 7
даже для уменьшения высоты и ширины листа формы вы можете использовать
[self.view.superview setBounds:CGRectMake(0, 0, 450, 480)];
Ответ 8
Подходы, описанные выше, необходимо настроить для iOS7:
// set desired bounds, then call -presentFromViewController:
@implementation PresentedViewController
{
CGRect _presentationBounds;
}
- (void)presentFromViewController:(UIViewController *)viewController
{
self.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
self.modalPresentationStyle = UIModalPresentationFormSheet;
_presentationBounds = self.view.bounds;
[viewController presentViewController:self animated:YES completion:nil];
}
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
if (!CGRectIsEmpty(_presentationBounds))
{
self.view.superview.bounds = _presentationBounds;
_presentationBounds = CGRectZero;
}
}
(Этот код также работает на iOS6.)
Ответ 9
Даже я боролся с той же проблемой довольно долгое время. После нескольких попыток из многих ответов, приведенных здесь, я придумал решение, которое сработало для меня довольно хорошо.
Вот код, представляющий контроллер вида.
SomeViewController *sovcObj = [[SomeViewController alloc] initWithNibName:@"SyncOptionsViewController" bundle:nil];
someObj.modalPresentationStyle = UIModalPresentationFormSheet;
someObj.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:someObj animated:YES completion:nil];
someObj.view.superview.bounds = CGRectMake(0, 0, 400, 400); // whatever width and height you want
В xib (если вы используете его) в разделе "Моделируемые показатели" выберите размер "Freeform".
Кроме того, вам нужно написать приведенный ниже код в представленном контроллере представления (например, SomeViewController в этом примере)
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.view.superview.bounds = CGRectMake(0, 0, 400, 400); // whatever width and height you want
}
Этот код также работает и для iOS 7
Ответ 10
Одним из решений является использование UIModalPresentationPageSheet для представления листа страницы и последующего изменения размера модального представления. Это полностью объяснено в этом ответе на другой вопрос.
Ответ 11
Измените размер модального представления "после", он представлен с использованием метода currentModalViewController. См. эту ссылку для изменения размера модального представления https://coderwall.com/p/vebqaq
Ответ 12
Вы можете использовать MZFormSheetController следующим образом:
MZFormSheetController *formSheet = [[MZFormSheetController alloc] initWithSize:customSize viewController:presentedViewController];
[presentingViewController mz_presentFormSheetController:formSheet animated:YES completionHandler:nil];
Ответ 13
Это решение работало для меня, поскольку у меня была такая же проблема.
Моя модальная структура выглядит следующим образом (я использую UIModalPresentationCurrentContext как для представления, так и для представленных контроллеров для достижения прозрачности в представленном VC)
ModalViewController
> UIView (view) - resized to the same size as the presenting controller but has semi-translucent background - done automatically
>> UIView (contentView) - the true view with the content of the popup - this is the one that got consistently placed at the top of the screen all the time
В ModalViewController я заменил следующий метод, чтобы исправить проблему с позиционированием:
- (void) viewWillLayoutSubviews(){
[super viewWillLayoutSubviews];
CGRect r = self.view.bounds();
self.contentView.center = CGPointMake(r.size.width/2,r.size.height/2);
}
Я фактически создаю и сортирую представление контента сначала, но по-разному.
Надеюсь, это поможет кому-то.