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

hpi*_*que 5 uiviewcontroller ipad uipopovercontroller modalviewcontroller ios

我想UIViewController在iPad中显示一个带有自定义框架的模态,以其父视图控制器为中心.

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

vc.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:cv animated:YES];
Run Code Online (Sandbox Code Playgroud)

我也试过使用一个弹出窗口,但据我所知,要么我不能居中,要么我无法隐藏箭头.

还有另一种显示模态视图控制器的方法吗?是否可以通过使用表单或弹出框来解决此问题?

Fáb*_*ira 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;
}
Run Code Online (Sandbox Code Playgroud)

如果它是你想要的唯一的东西它工作正常.但我发现Apple的模态视图控制器的实现有点适得其反,因为你无法访问它的任何底层部分,因此你无法完全动画它们.如果你想拥有自己的过渡,这很有用.

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


小智 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;
Run Code Online (Sandbox Code Playgroud)

我的自定义模态视图通常是这样的:

@protocol ModalViewDelegate <NSObject>
- (void)performSelectorOnDelegate:(SEL)selector;
@end

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

@property(nonatomic, assign) id<ModalViewDelegate> delegate;
Run Code Online (Sandbox Code Playgroud)

在我的呈现视图控制器中,我通常会执行以下操作:

- (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]; 
}
Run Code Online (Sandbox Code Playgroud)

使用在这两个类上定义的委托为我提供了相当开放的访问权限来操纵我的呈现控制器以及我的呈现和解散。唯一的缺点是当它用在带有导航栏的视图上时,由于呈现控制器视图的边界将不包含导航栏的边界,使其保持开放状态以供交互,有多种方法可以解决此问题,但不是其中之一非常漂亮(添加到导航控制器的视图是一种选择)。