Domanda

Voglio mostrare un UIViewController modale con un telaio su misura in iPad, centrato sulla parte superiore del suo controller vista padre.

Ho provato ad utilizzare un foglio di forma, ma per quanto so l'effetto telaio e ombra non può essere modificata.

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

Ho anche provato ad utilizzare un popover, ma per quanto ne so o io non riesco a centrare o non posso nascondere la freccia.

C'è un altro modo per mostrare i controller di vista modale? E 'possibile risolvere questo problema utilizzando i fogli di modulo o popovers?

È stato utile?

Soluzione

Non c'è un modo ufficiale per fare questo però è possibile ottenere il comportamento desiderato scrivendo una visualizzazione personalizzata che mantiene un riferimento o delegato di interagire con la sua presentazione controller della vista e aggiungendolo alla gerarchia della vista. Per ottenere davvero il modale sentire è anche possibile effettuare una mascherina trasparente sopra il controller che presenta appena sotto la vista 'modale'. Ho fatto questo in un certo numero di applicazioni e di solito funziona alla grande. È probabile che sia necessario per rendere la vista modulo elettronico personalizzato in modo da poter intercettare tocchi e più elegantemente animare la sua presentazione.

La mia mascherina trasparente è di solito qualcosa di simile:

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

Il mio personalizzato vista modale è di solito qualcosa di simile:

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

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

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

Nella mia presentazione di controller della vista Io di solito fare quanto segue:

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

mi Utilizzando i delegati definiti in due classi dà praticamente libero accesso a manipolare il mio controller presenta così come la mia presentazione e il licenziamento, se lo desideri. L'unico aspetto negativo di questo è quando viene utilizzato su una vista con un NavigationBar, come i limiti di vista del controllore che presenta non conterrà i limiti del NavigationBar lasciandolo aperto per l'interazione, ci sono modi per aggirare questo, ma non di loro sono molto carino (aggiungendo alla visualizzazione del controller di navigazione è un'opzione).

Altri suggerimenti

Sto usando il seguente metodo per creare una vista di controllo modale con qualsiasi formato al centro dello schermo. Si può cambiare per centrare nel controller della vista genitore, se si desidera. Questo è il lavoro da storyboard in modo forse possibile inviare il controller della vista come un argomento invece. Ma a parte questo, fa quello che è necessario.

Nota. Ho scoperto che se si tenta di mostrare un altro modale su questo si tornerà al formato originale

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

Se è l'unica cosa che si desidera funziona benissimo. Ma quello che ho trovato è che l'attuazione di Apple di controller di vista modale è un po 'controproducente, come non si può accedere da suoi sottostanti parti e quindi non è possibile animare completamente. Utile se si vuole avere le proprie transizioni.

E non rientra anche nella categoria di un controller di vista bambino così com'è su tutte le altre viste nella finestra.

Questo non può assolutamente rispondere alla tua domanda. Ma io chiamo il codice da un rightbuttonitem su un controller di navigazione che ho già messo in cima a una vista di dettaglio di una splitviewcontroller.

Questa vista modale copre l'intero schermo. Forse si vuole coprire, ad esempio, la visualizzazione dei dettagli solo se chiamato in 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];

}

Io preferisco la risposta di fabio-oliveira ma richiede qualche aggiustamento per permettere di lavorare su ambiente multi filo IOS 7 di:

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

Ora inserire il codice di centraggio nel bersaglio VC in modo che il nuovo thread fa il lavoro:

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

Oh sì, se si stanno sostenendo quelle belle IOS 5 iPad 1 di, essere sicuri di lasciare che la rotazione bersaglio vc:

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

Nel mio caso, ignorando viewWillLayoutSubviews ha fatto il trucco.

- (void)viewWillLayoutSubviews {
        [super viewWillLayoutSubviews];

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

Niente di più era necessario per cambiare la posizione e limiti di ModalViewController.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top