2012-08-25 18 views
5

Ho un UIView che è a livello di codice in fase di creazione:Come rilevare la rotazione per un UIView programatically generato

- (id)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; 
    if (self) { 
     self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.5]; 

     UIImageView* closeButton = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"modal_close.png"]]; 

     closeButton.frame = CGRectMake(self.frame.size.width*.89, self.frame.size.height*.09, closeButton.frame.size.width, closeButton.frame.size.height); 

     UIButton* button = [[UIButton alloc] initWithFrame:CGRectMake(self.frame.size.width*.89, self.frame.size.height*.09,20, 20)]; 

     [button addTarget:self action:@selector(close) forControlEvents:UIControlEventTouchUpInside]; 

     UIView* mainView = [[UIView alloc] initWithFrame:CGRectMake(self.frame.size.width*.1,self.frame.size.height*.1,self.frame.size.width*.8,self.frame.size.height*.8)]; 

     mainView.backgroundColor = [UIColor whiteColor]; 
     _displayMainView = mainView;   

     [self addSubview:_displayMainView]; 
     [self addSubview:closeButton]; 
     [self addSubview:button]; 

     mainView = nil; 
     closeButton = nil; 
    } 
    return self; 
} 

Come posso rilevare la rotazione? Questo è quello di agire come una modale sopra un'altra vista esistente. Questa è solo un'app per iPad, se questo è importante.

+0

Vuoi dire l'angolo del UIView di rotazione, e l'orientamento del dispositivo? –

+0

Vedere questa eccellente risposta: http://stackoverflow.com/a/3897243/194544 – beryllium

risposta

5

penso che si hanno due opzioni:

  1. si mette la visualizzazione in un costume UIViewController e l'override del metodo shouldAutorotateToInterfaceOrientation: per restituire YES per tutti gli orientamenti si desidera supportare. Il controller della vista ruoterà e ridimensionerà automaticamente il contenuto (la tua vista). Devi solo assicurarti di avere il corretto autoresizeMask (o vincoli, se stai usando l'autolayout).
  2. Osservate direttamente le modifiche all'orientamento dei dispositivi con l'accelerometro. Quindi puoi modificare la tua vista quando necessario.

È davvero il primo approccio che dovresti scegliere se puoi.

42

Si potrebbe ottenere il dispositivo per iniziare a generare le notifiche di rotazione:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 

Aggiungere il proprio selettore in qualità di osservatore per una notifica di rotazione del dispositivo:

 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil]; 

E poi scrivere il gestore di notifica

- (void)deviceOrientationDidChange:(NSNotification *)notification { 
    //Obtain current device orientation 
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 

     //Do my thing 
} 

Ricordarsi di rimuovere l'osservatore quando il metodo dealloc di te UIView personalizzato viene chiamato (o quando hai finito) e smette di generare anche le notifiche di modifica del dispositivo.

-(void) dealloc{ 
[[NSNotificationCenter defaultCenter] removeObserver: self]; 
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; 
} 

Questo può aiutare con la tua domanda?

+0

Non utilizzare questo dispositivo poiché attiverà l'accelerometro del dispositivo. L'accelerometro rimarrà attivo finché non chiamate "endGeneratingDeviceOrientationNotifications'. Ma se la tua vista è una vista cella, non verrà mai deallocata finché non avrai deallocato la vista tabella (cosa che probabilmente non succederà). Puoi usare 'se UIScreen.main.bounds.height> UIScreen.main.bounds.width' invece. –

3

sto riscrivendo la risposta di @ clearwater82 per Swift 3 dal momento che il suo approccio è quello che ho finito per usare:

ho aggiunto il seguente codice nel metodo init del mio punto di vista (per un controller sarebbe in esso è viewDidLoad metodo):

// Handle rotation 
UIDevice.current.beginGeneratingDeviceOrientationNotifications() 
NotificationCenter.default.addObserver(
    self, 
    selector: #selector(self.orientationChanged(notification:)), 
    name: NSNotification.Name.UIDeviceOrientationDidChange, 
    object: nil 
) 


ho poi aggiunto il metodo orientationChanged al mio punto di vista. È possibile rinominare questo metodo come si desidera, basta ricordarsi di rinominare anche nel frammento di codice di cui sopra:

// Called when device orientation changes 
@objc func orientationChanged(notification: Notification) { 
    // handle rotation here 
} 


Infine ho aggiunto il metodo deinit per rimuovere le notifiche inutili quando la vista viene rimosso:

deinit { 
    NotificationCenter.default.removeObserver(self) 
    UIDevice.current.endGeneratingDeviceOrientationNotifications() 
} 

Nei quest'ultimo frammento non è di rimuovere la stessa vista da osservatori notifica e quindi impedire al dispositivo di generazione di altre notifiche di rotazione. Questo approccio era quello di cui avevo bisogno ma potresti non voler impedire che le notifiche vengano generate quando la vista viene rimossa.

Spero che questo è utile, applausi

Problemi correlati