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

相關問題