簡體   English   中英

在iPad中顯示帶自定義框架的模態視圖控制器

[英]Show modal view controller with custom frame in iPad

我想在iPad中顯示一個帶有自定義框架的模態UIViewController ,它位於其父視圖控制器的頂部。

我嘗試使用表單,但據我所知,框架和陰影效果無法更改。

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

我也試過使用一個彈出框,但據我所知,要么我不能居中,要么我無法隱藏箭頭。

還有另一種顯示模態視圖控制器的方法嗎? 是否可以通過使用表單或彈出框來解決此問題?

我正在使用以下方法創建一個模式視圖控制器,其中任何給定的大小都在屏幕中心。 如果需要,您可以將其更改為父視圖控制器的中心。 這是從故事板開始工作,因此您可以將視圖控制器作為參數發送。 但除此之外,它可以滿足您的需求。

注意:我發現如果你試圖在這個上顯示另一個模態,它將恢復到原始大小。

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

如果它是你想要的唯一的東西它工作正常。 但我發現Apple的模態視圖控制器的實現有點適得其反,因為你無法訪問它的任何底層部分,因此你無法完全動畫它們。 如果你想擁有自己的過渡,這很有用。

並且它也不屬於子視圖控制器的類別,因為它代表窗口中的所有其他視圖。

沒有正式的方法可以執行此操作,但是您可以通過編寫自定義視圖來獲得所需的行為,該視圖使引用或委托與其呈現的視圖控制器交互並將其添加到視圖層次結構中。 要真正獲得模態感覺,您還可以在“模態”視圖下方的呈現控制器上放置透明覆蓋。 我已經在許多應用程序中完成了這項工作,它通常效果很好。 您可能需要制作自定義疊加視圖,以便您可以攔截觸摸並更優雅地為其演示設置動畫。

我透明的疊加層通常是這樣的:

@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的邊界,使其保持打開以進行交互,有多種方法可以繞過它而不是它們非常漂亮(添加到導航控制器的視圖是一個選項)。

我更喜歡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>); 
}

不需要更改ModalViewController的位置和界限。

這可能無法完全回答您的問題。 但是我在導航控制器上從右側按鈕調用以下代碼,我之前放置在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];

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM