Popover с ModalPresentationStyle не ориентирован на iOS 7 iPad
У меня проблема с iOS 7, которая кажется ошибкой, или я просто ничего не делаю правильно. У меня есть modalViewController, который появляется как popover на iPad с ModalPresentationStyle. И это не стандартный размер, нестандартный размер.
Вот код:
myViewController *myVC = [[myViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:myVC];
[nav setModalPresentationStyle:UIModalPresentationFormSheet];
[nav setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal];
[self presentViewController:nav animated:YES completion:nil];
nav.view.superview.bounds = CGRectMake(0, 0, 320, 465);
Все работает отлично в iOS 6, но в iOS 7 оно не сосредоточено.
Но если я установил ModalTransitionStyle в UIModalTransitionStyleCrossDissolve, он отлично работает. Но только в этом режиме.
Может, кто-то тоже наткнулся на это и знает, как это исправить? Я не большой поклонник растворения эффекта.
Спасибо.
Ответы
Ответ 1
У меня есть метод, в котором старый стиль модального представления fromsheet
работает с iOS <=7
, хотя вы можете установить custom height and width
.
Имейте в виду, что этот метод может не работать в любой новой версии в будущем
- (void) hackModalSheetSize:(CGSize) aSize ofVC:(UIViewController *) aController;
{
void (^formSheetBlock) (void) = ^{
int preferredWidth = aSize.width;
int preferredHeight = aSize.height;
CGRect frame = CGRectMake((int) 1024/2 - preferredWidth/2,
(int) 768/2 - preferredHeight/2,
preferredWidth, preferredHeight);
aController.view.superview.frame = frame;
if([aController respondsToSelector:@selector(edgesForExtendedLayout)]) { //ios7
aController.view.superview.backgroundColor = [UIColor clearColor];
} else { // < ios7
UIImageView *backgroundView = [aController.view.superview.subviews objectAtIndex:0];
[backgroundView removeFromSuperview];
}
};
//on ios < 7 the animation would be not as smooth as on the older versions so do it immediately
if(![self respondsToSelector:@selector(edgesForExtendedLayout)]) {
formSheetBlock();
return;
}
double delayInSeconds = .05;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
formSheetBlock();
});
}
Ответ 2
У меня была та же проблема. Я решил это, используя другой подход, нашёл здесь.
Это решение предлагает использовать метод (void)viewWillLayoutSubviews
Итак, в случае @Manuel M. внутри GeneralSettingsViewController
добавьте следующий код:
// GeneralSettingsViewController
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.view.superview.bounds = CGRectMake(0, 0, 497, 375);
}
И вам больше не понадобится этот код:
self.generalSettingsVC.view.superview.frame = CGRectMake(0, 0, 497, 375);
self.generalSettingsVC.view.superview.center = self.view.center;
Для @titicaca вы используете UINavigationController
, я не тестировал его с помощью этого контроллера, но вы можете попробовать то же самое решение, о котором я говорил, расширяя UINavigationController
и перезаписывая метод viewWillLayoutSubviews
.
[EDIT]
Для @titicaca я попробовал это в новом проекте, и для меня это сработало. То, что я сделал, это иметь настраиваемый контроллер вида навигации CustomNavigationController
, переопределяющий viewWillLayoutSubviews
следующим образом:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.view.superview.bounds = CGRectMake(0, 0, 330, 284);
}
Затем контроллер представления, представляющий CustomNavigationController
, должен выполнить код, подобный этому:
UIViewController *myVC = [[UIViewController alloc] init];
[myVC.view setBackgroundColor:[UIColor redColor]];
CustomNavigationController *nav = [[CustomNavigationController alloc] initWithRootViewController:myVC];
[nav setModalPresentationStyle:UIModalPresentationFormSheet];
[nav setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal];
[self presentViewController:nav animated:YES completion:nil];
Вам нужно убедиться, что размеры self.view.superview.bounds = CGRectMake(0, 0, 330, 284);
являются четными числами, иначе текст внутри становится нечетким, если есть
Ответ 3
Для меня проблема заключалась в вызове becomeFirstResponder
в текстовое поле в viewDidAppear
представленного контроллера представления. Кажется, теперь это ошибка. Решение было обернуть его простым dispatch_async
:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
dispatch_async(dispatch_get_main_queue(), ^{
[self.userNameTextField becomeFirstResponder];
});
}
Ответ 4
То же самое для меня... Я еще не знаю, как его решить. Я сейчас работаю над этой проблемой, поэтому все, что я получаю, я поделюсь ею!
Это мой код.
-(IBAction)showGeneralSettings:(id)sender{
self.generalSettingsVC = [[GeneralSettingsViewController alloc] initWithNibName:@"GeneralSettingsView" bundle:nil];
//Present the view controller as a modal with a custom size (important to do after presenting it)
self.generalSettingsVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:self.generalSettingsVC animated:YES completion:nil];
self.generalSettingsVC.view.superview.frame = CGRectMake(0, 0, 497, 375);
self.generalSettingsVC.view.superview.center = self.view.center;
}
Ответ 5
Решение выше не работает для меня. Я использовал следующее:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:theViewController];
navigationController.modalPresentationStyle=UIModalPresentationFormSheet;
[self presentViewController:navigationController animated:YES completion:nil];
if([[UIDevice currentDevice] userInterfaceIdiom] != UIUserInterfaceIdiomPhone){
navigationController.view.superview.frame = CGRectMake(0, 0, 320, 544);
navigationController.view.frame =CGRectMake(108, 0, 320, 544);
navigationController.view.superview.backgroundColor=[UIColor clearColor];
}
Ответ 6
Я немного пошла по этому поводу, используя подклассифицированный контроллер навигации и AutoLayout в Swift, чтобы центрировать представление в супервизоре с заданной шириной и высотой. В моем конкретном случае мне нужна поддержка iPad и iOS7-8 (есть некоторые константы, специфичные для моего проекта в этом коде, но вы получаете идею)...
class CenteredModalNavigationController: UINavigationController {
// MARK:- Methods
override func viewDidLoad() {
super.viewDidLoad()
preferredContentSize = CGSizeMake(320, 480) // iOS8 only
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// iOS7 support for iPad custom sized form-sheet modal.
if kDeviceiOS7 && kDeviceiPad {
if view.superview == nil {
Log.warning("Failed to find superview")
return
}
view.superview!.setTranslatesAutoresizingMaskIntoConstraints(false)
// Give the superview constraints to center the view inside it.
var viewBindingsDict: NSMutableDictionary = NSMutableDictionary()
viewBindingsDict.setValue(view, forKey: "view")
viewBindingsDict.setValue(view.superview!, forKey: "superview")
let centerXConstraints = NSLayoutConstraint.constraintsWithVisualFormat("V:[superview]-(<=1)-[view]",
options: .AlignAllCenterX,
metrics: nil,
views: viewBindingsDict)
view.superview!.addConstraints(centerXConstraints)
let centerYConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:[superview]-(<=1)-[view]",
options: .AlignAllCenterY,
metrics: nil,
views: viewBindingsDict)
view.superview!.addConstraints(centerYConstraints)
// Now give it a width/height and it should float in the middle of our superview.
AutoLayoutHelper.addWidthConstraint(view,
aSuperView: view.superview!,
width: 320)
AutoLayoutHelper.addHeightConstraint(view,
aSuperView: view.superview!,
height: 480)
}
}
override func prefersStatusBarHidden() -> Bool {
return true
}
override func disablesAutomaticKeyboardDismissal() -> Bool {
// DEVNOTE: Because this is shown in a modal, this is required to stop keyboard dismiss issues.
return true
}
}
...
class AutoLayoutHelper: NSObject {
class func addHeightConstraint(aChildView:UIView, aSuperView:UIView, height:CGFloat) {
var constraint = NSLayoutConstraint(item: aChildView,
attribute: NSLayoutAttribute.Height,
relatedBy: NSLayoutRelation.Equal,
toItem: nil,
attribute: NSLayoutAttribute.NotAnAttribute,
multiplier: 1.0,
constant: height)
aSuperView.addConstraint(constraint)
}
class func addWidthConstraint(aChildView:UIView, aSuperView:UIView, width:CGFloat) {
var constraint = NSLayoutConstraint(item: aChildView,
attribute: NSLayoutAttribute.Width,
relatedBy: NSLayoutRelation.Equal,
toItem: nil,
attribute: NSLayoutAttribute.NotAnAttribute,
multiplier: 1.0,
constant: width)
aSuperView.addConstraint(constraint)
}
}