带有 ModalPresentationStyle 的弹出框不在 iOS 7 iPad 中居中
Posted
技术标签:
【中文标题】带有 ModalPresentationStyle 的弹出框不在 iOS 7 iPad 中居中【英文标题】:Popover with ModalPresentationStyle is not centered in iOS 7 iPad 【发布时间】:2013-09-22 04:45:59 【问题描述】:我在使用 ios 7 时遇到了一个问题,这似乎是一个错误,或者我没有做正确的事情。我有 modalViewController,它在 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】:我遇到了同样的问题。我已经通过使用另一种方法解决了这个问题,发现 here。
这个方案提出的是使用(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
方法。
[编辑]
对于@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);
的尺寸是偶数,否则里面的文字会变得模糊,如果有的话
【讨论】:
我想知道是否有人可以解释为什么 a) 必须调用view.superview.bounds
属性才能解决此问题,以及 b) 如何为矩形的原点传入 (0,0) 导致它居中?
我发现viewWillAppear:
是放置self.view.superview.bounds=xxx
的更好位置,因为它比viewWillLayoutSubviews
更早被调用【参考方案2】:
对我来说,问题是在呈现的视图控制器的 viewDidAppear
中的文本字段上调用 becomeFirstResponder
。现在似乎是一个错误。解决方案是将其包装在一个简单的dispatch_async
:
- (void)viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
dispatch_async(dispatch_get_main_queue(), ^
[self.userNameTextField becomeFirstResponder];
);
【讨论】:
【参考方案3】:对我来说也是一样...我还不知道如何解决它。我目前正在处理这个问题,所以我会分享任何我得到的东西!
这是我的代码。
-(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;
【讨论】:
嘿曼努埃尔,你找到解决办法了吗? 嘿! @Tamara Bernad 的解决方案非常有效。尝试一下。我不能投票得那么好,因为我还没有名声:( 不幸的是,它对我没有那么好。它将弹出框放在中心,但它不是我的尺寸,它只是标准尺寸的弹出框窗口,我的东西也居中..【参考方案4】:我有一个方法,旧的自定义模式演示样式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();
);
【讨论】:
我会接受这个答案,因为这对我有用,至少现在是这样。虽然我最终使用了 MZFormSheetController——它确实是一个很棒的 ios 7 风格的解决方案,在两个 ios 版本中都适用于我。虽然我真的很想在未来弄清楚如何使用原生 ios 套件来处理这个问题,但现在似乎是一个错误。 嘿,它不起作用,它只是显示弹出窗口,然后再次进入表单中的完整视图。任何想法***.com/questions/30615075/…【参考方案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】:我在 Swift 中使用子类导航控制器和 AutoLayout 进行了稍微不同的处理,以将超级视图中的视图以设定的宽度和高度居中。我的特殊情况需要 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)
【讨论】:
以上是关于带有 ModalPresentationStyle 的弹出框不在 iOS 7 iPad 中居中的主要内容,如果未能解决你的问题,请参考以下文章
如何为自定义modalPresentationStyle禁用设置supportedInterfaceOrientations
containerView的自定义动画中的modalPresentationStyle .overCurrentContext返回黑屏
PresentViewController 与 ModalPresentationStyle “UIModalPresentationFormSheet” IOS 8
iOS 通用二进制 - 切换 ModalPresentationStyle