在iPad中显示带有自定义框架的模态视图控制器

在iPad中显示带有自定义框架的模态视图控制器,ipad,ios,uiviewcontroller,uipopovercontroller,modalviewcontroller,Ipad,Ios,Uiviewcontroller,Uipopovercontroller,Modalviewcontroller,我想在iPad中显示一个带有自定义框架的模态视图控制器,该框架位于其父视图控制器的顶部 我试着使用表单,但据我所知,框架和阴影效果无法更改 vc.modalPresentationStyle = UIModalPresentationFormSheet; [self presentModalViewController:cv animated:YES]; 我也试过用一个popover,但据我所知,要么我不能居中,要么我不能隐藏箭头 是否有其他方式显示模态视图控制器?是否可以使用表单或弹出框解决

我想在iPad中显示一个带有自定义框架的模态视图控制器,该框架位于其父视图控制器的顶部

我试着使用表单,但据我所知,框架和阴影效果无法更改

vc.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:cv animated:YES];
我也试过用一个popover,但据我所知,要么我不能居中,要么我不能隐藏箭头


是否有其他方式显示模态视图控制器?是否可以使用表单或弹出框解决此问题?

这可能无法完全回答您的问题。但我从导航控制器上的rightbuttonitem调用以下代码,我之前将其放置在splitviewcontroller的详细视图顶部

此模式视图覆盖整个屏幕。例如,是否仅当在detailviewcontroller中调用时才覆盖详图视图

- (void)aboutAction {

About *about = [[About alloc] init];
UINavigationController *nav1 = [[UINavigationController alloc]initWithRootViewController:about];
[about release];
nav1.navigationBar.barStyle = UIBarStyleBlackOpaque;
nav1.modalPresentationStyle = UIModalPresentationFullScreen;
nav1.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:nav1 animated:YES ];
[nav1 release];

}

没有正式的方法可以做到这一点,但是您可以通过编写一个自定义视图来获得所需的行为,该视图保留一个引用或委托以与其呈现的视图控制器交互,并将其添加到视图层次结构中。为了真正获得模态的感觉,您还可以在“模态”视图正下方的呈现控制器上放置一个透明覆盖层。我在很多应用程序中都这么做过,通常效果都很好。您可能需要创建自定义覆盖视图,以便可以拦截触摸并更优雅地设置其显示动画

我的透明覆盖通常是这样的:

@protocol TransparentOverlayDelegate <NSObject>

@optional
- (void)transparentOverlayWillDismiss:(TransparentOverlay *)backgroundTouch;
- (void)transparentOverlayDidDismiss:(TransparentOverlay *)backgroundTouch;
@end


@interface TransparentOverlay : UIView {

    id<TransparentOverlayDelegate> _delegate;
    UIView *_contentView;
    CGFloat _pAlpha;
}

@property(nonatomic, assign) id<TransparentOverlayDelegate> delegate;
@property(nonatomic, retain) UIView *contentView;
@property(nonatomic, assign) CGFloat pAlpha;

- (void)presentTransparentOverlayInView:(UIView *)view;
- (void)dismissTransparentOverlay:(BOOL)animated;
@protocol ModalViewDelegate <NSObject>
- (void)performSelectorOnDelegate:(SEL)selector;
@end

@interface ModalView : UIView {
    id<ModalViewDelegate> _delegate;
}

@property(nonatomic, assign) id<ModalViewDelegate> delegate;

使用这两个类中定义的委托,我可以非常开放地操作演示控制器以及所需的演示和解聘。唯一的缺点是,当它在带有导航栏的视图上使用时,由于呈现控制器视图的边界将不包含导航栏的边界,从而使其为交互打开,因此有一些方法可以解决这个问题,但不是很漂亮(添加到导航控制器的视图是一个选项).

我正在使用以下方法创建一个模态视图控制器,该控制器具有屏幕中心的任何给定大小。如果需要,可以在父视图控制器中将其更改为“中心”。 这是从情节提要开始的,因此您可以将视图控制器作为参数发送。除此之外,它还满足你的需要

注意:我发现如果您尝试在这个模式上显示另一个模式,它将返回到原始大小。

- (UIViewController *) presentModalViewControllerWithIdentifier:(NSString *)identifier 
                                                        andSize:(CGSize)size 
                                        andModalTransitionStyle:(UIModalTransitionStyle)modalTransitionStyle {
    UIViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];


    viewController.modalPresentationStyle = UIModalPresentationPageSheet;
    viewController.modalTransitionStyle = modalTransitionStyle;
    [self presentModalViewController:viewController animated:YES];
    viewController.view.superview.autoresizingMask = 
    UIViewAutoresizingFlexibleTopMargin | 
    UIViewAutoresizingFlexibleBottomMargin | 
    UIViewAutoresizingFlexibleLeftMargin | 
    UIViewAutoresizingFlexibleRightMargin;    
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    viewController.view.superview.frame = CGRectMake(0, 0, size.width, size.height);
    CGPoint center = CGPointMake(CGRectGetMidX(screenBounds), CGRectGetMidY(screenBounds));
    viewController.view.superview.center = UIDeviceOrientationIsPortrait(self.interfaceOrientation) ? center : CGPointMake(center.y, center.x);

    return viewController;
}
如果这是你唯一想要的东西,它很好用。 但我发现苹果的模态视图控制器的实现有点适得其反,因为你无法访问它的任何底层部分,所以你无法完全动画化它们。如果您希望拥有自己的转换,则此功能非常有用


而且它也不属于子视图控制器的范畴,因为它位于窗口中的所有其他视图之上。

我更喜欢fabio oliveira的答案,但它需要一些调整才能在IOS 7的多线程环境中工作:

- (UIViewController *)presentModalViewControllerWithId:(NSString *)identifier
                                           andSize:(CGSize)size
                           andModalTransitionStyle:(UIModalTransitionStyle)style
{
    UIViewController *viewController = 
            [self.storyboard instantiateViewControllerWithIdentifier:identifier];

    viewController.modalPresentationStyle = UIModalPresentationPageSheet;
    viewController.modalTransitionStyle = style;

    [self presentViewController:viewController animated:YES completion:nil];

    viewController.view.superview.autoresizingMask = 
        UIViewAutoresizingFlexibleTopMargin    |
        UIViewAutoresizingFlexibleBottomMargin | 
        UIViewAutoresizingFlexibleLeftMargin   | 
        UIViewAutoresizingFlexibleRightMargin;

    viewController.view.superview.frame = 
                   CGRectMake(0, 0, size.width, size.height);

   return viewController;
}
现在,将定心代码放在目标VC中,以便新螺纹完成工作:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    CGPoint center = CGPointMake(CGRectGetMidX(screenBounds),
                                 CGRectGetMidY(screenBounds));

    self.view.superview.center =
    UIDeviceOrientationIsPortrait(self.interfaceOrientation) ? 
                                       center : CGPointMake(center.y, center.x);
}
哦,是的,如果你支持那些可爱的IOS 5 iPad 1,一定要让目标vc轮换:

- (BOOL)shouldAutorotateToInterfaceOrientation:
                         (UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

在我的例子中,重写
viewWillLayoutSubviews
成功了

- (void)viewWillLayoutSubviews {
        [super viewWillLayoutSubviews];

    self.view.superview.frame = CGRectMake(100.f, 100.f, <width>, <height>); 
}
-(void)视图将布局子视图{
[超级视图将布局子视图];
self.view.superview.frame=CGRectMake(100.f,100.f,);
}

更改
ModalViewController

的位置和边界无需更多操作,您可以在任何地方使用presentPopoverFromRect显示一个popover,甚至可以使其行为模式化,但唯一的缺点是无法隐藏箭头ModalViewDelegate中的code>?这对我帮助很大。谢谢。+1多年来我一直在尝试调整modals的大小,但是StackOverflow上的任何解决方案都没有帮助。它要么没有正确地调整视图的大小/居中,要么不能处理所有的TransitionStyle。这个解决方案是完美的!下面是IOS 7更新,它可能会删除上面提到的由子代产生的vc问题。这对我不起作用。我仍然有默认的x和y页边距从屏幕模式。我可以更改高度和宽度,但与主屏幕的x和y偏移是默认值。@tanmaykhandelwal这是旧的,在iOS 7旧之前。对于iOS 7及更高版本,请检查过渡代理和演示控制器(此控制器仅适用于iOS 8)。您好@gjpc,我使用了您的代码,它工作正常,但当它弹出时,我的意思是,当显示modalView时,它会从角落打开,并朝中心移动。你找到这个了吗?@Ranjit我使用andModAltTransitionStyle:UIModAltTransitionStyleCoverVertical];它们从底部出现,然后从底部离开我试着使用modaltransationstyle:uimodaltransationstylecoververtical];,但模态出现在下角,当我关闭它时,它会在底部的中心关闭。谢谢。这对我有用。上述方法中没有一种是有效的。你的键盘是一个救生圈。这对我来说很有效,直到用户活动将iPad键盘带到屏幕上,此时模式又回到了原来的位置。
- (void)viewWillLayoutSubviews {
        [super viewWillLayoutSubviews];

    self.view.superview.frame = CGRectMake(100.f, 100.f, <width>, <height>); 
}