5

我想在iPad中以其父视图控制器顶部为中心显示具有自定义框架的模式UIViewController在iPad中显示具有自定义框架的模式视图控制器

我尝试使用表单,但据我所知,帧和阴影效果无法更改。

vc.modalPresentationStyle = UIModalPresentationFormSheet; 
[self presentModalViewController:cv animated:YES]; 

我也尝试过使用弹窗,但据我所知,要么我不能居中它,要么我不能隐藏箭头。

有没有另一种方式来显示模态视图控制器?是否可以通过使用表单或弹出来解决这个问题?

+1

您可以使用presentPopoverFromRect在任何地方显示弹出窗口,甚至可以使其表现模态,但只有缺点是无法隐藏箭头。 – Anna 2010-11-01 03:04:17

回答

4

还有就是要做到这一点,但是你可以通过写这使参考或委托其呈现视图控制器交互的自定义​​视图并将其添加到视图层次获得所需的行为没有正式的办法。要真正获得模态感,您还可以在“模态”视图下方的展示控制器上放置透明覆盖层。我已经在很多应用程序中完成了这项工作,并且通常效果很好。您可能需要制作自定义叠加视图,以便拦截触摸并更优雅地呈现其演示文稿。

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

@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; 

在我呈现视图控制器我通常会做到以下几点:

- (void)presentModalController { 
    TransparentOverlay *to = [[[TransparentOverlay alloc] initWithFrame:self.view.bounds] autorelease]; 
    to.delegate = self; 

    ModalView *mv = [[ModalView alloc] initWithFrame:CGRectMake(500, 500, 300, 300)]; 
    mv.delegate = self; 

    to.contentView = mv; 
    [mv release]; 

    [to presentTransparentOverlayInView:self.view]; 
} 

使用在两个类上定义的委托给我非常开放的访问来操纵我的演示控制器以及我的演示和解雇所需。唯一的缺点是当它用在带有NavigationBar的视图上时,由于呈现控制器视图的边界将不包含NavigationBar的边界,从而将其打开以进行交互,所以有办法解决这个问题,但不能解决这个问题非常漂亮(添加到导航控制器的视图是一种选择)。

+0

' - (void)performSelectorOnDelegate:(SEL)选择器;'ModalViewDelegate'中的目的是什么? – 2012-06-21 21:20:23

1

这可能不会完全回答你的问题。但是我从一个导航控制器上的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]; 

} 
6

我使用以下方法创建一个以屏幕中心为中心的任意给定大小的模式视图控制器。如果需要,您可以将其更改为父视图控制器的中心。 这是从故事板工作,所以你也许可以发送视图控制器作为参数。但除此之外,它可以满足你的需求。

注意:我发现如果您尝试显示另一种模式,则会返回到原始大小。

- (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; 
} 

如果这是你想要的唯一的东西,它工作正常。 但我发现,苹果的模态视图控制器的实现是有点反作用,因为你不能访问它的任何底层部分,所以你不能完全制作它们的动画。如果你想拥有你自己的转换,这很有用。

它也不属于子视图控制器的类别,因为它代表了窗口中的所有其他视图。

+0

这对我有很大的帮助。谢谢。 – 2012-12-27 00:55:29

+0

+1我试图调整模态的年龄,但StackOverflow上的解决方案都没有帮助。它没有正确调整视图的大小或居中,或者它不适用于所有transitionStyles。这个解决方案是完美的! – 2013-02-07 12:08:16

+0

IOS 7更新如下,它可能会删除上面提到的孩子产卵vc问题 – gjpc 2013-10-14 00:17:08

1

我喜欢法比奥 - 奥利维拉的答案,但它需要一些调整,以允许其在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; 
} 
+0

hi @gjpc,我用你的代码,它工作正常,但是当它弹出时,我的意思是当modalView被提交时,它从角落打开并且朝向中心消失。你有没有找到这个。 – Ranjit 2013-10-23 07:53:39

+0

@Ranjit我使用andModalTransitionStyle:UIModalTransitionStyleCoverVertical];他们从底部出现,并通过底部 – gjpc 2013-10-24 20:30:11

+0

我试过使用ModalTransitionStyle:UIModalTransitionStyleCoverVertical];但模态显示从底部角落,当我解雇它在底部中心解散。 – Ranjit 2013-10-25 06:21:45

1

在我的情况下,覆盖viewWillLayoutSubviews伎俩。

- (void)viewWillLayoutSubviews { 
     [super viewWillLayoutSubviews]; 

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

没有更多的需要更改ModalViewController的位置和范围。

+0

这对我来说很有效,直到用户的活动将iPad的键盘带到屏幕上,此时模式才回到原来的位置。 – 2015-04-27 19:00:21

相关问题