Esto es un dolor y sigue siendo cierto en iOS 4.2 para iPads. La forma en que resolvió esto es subclase el UIView
asociado con el UIViewController
. Hice esto en el constructor de interfaz, pero supongo que uno también podría hacer esto en código de alguna manera. En el constructor de interfaces, seleccione UIView en el UIViewController
y luego presione el ícono (i) en la esquina superior derecha de la ventana del Inspector. Debajo de la identidad de clase, presione la ventana emergente y elija la subclase UIView a continuación.
El enfoque es que esta subclase UIView reemplaza el método layoutSubviews, encuentra el siguiente UIViewController
, determina si se implementa un método reactToLayout (que es un método que hay que aplicar en la subclase UIViewController
para el controlador de vista de este punto de vista) . Si el método reactToLayout existe en el primer UIViewController
encontrado, se invoca.
El método reactToLayout en el controlador de vista y luego hace lo que uno tiene que hacer lo que será capaz de hacer con éxito desde el marco de la vista está configurado correctamente en ese momento (al contrario que en ViewDidLoad
, viewWillAppear
, o incluso viewDidAppear
). Tengo un método que llamo cada vez que cambia la orientación o el marco. Es un problema, pero guardo el último cuadro presentado y la última orientación presentada en las variables internas del controlador de vista. El diseño interno de la nueva orientación o el método de cambio de marco los compara con el marco actual de la vista y la orientación solicitada o actual para que no se distribuya innecesariamente una y otra vez.
Aquí está el código:
UILayoutSubviewsView.h
#import <UIKit/UIKit.h>
@interface UILayoutSubviewsView : UIView {
}
@end
UILayoutSubviewsView.m
#import "UILayoutSubviewsView.h"
// Create this to avoid a warning that this method does not exist for UIViewControllers
// this is OK since we check to see that it does exist before invoking it
@interface UIViewController(UndocumentedMethodForUIViewController)
-(void) reactToLayout;
@end
@implementation UILayoutSubviewsView
// Pass this up to our view controller if it supports the reactToLayout method
// (this is the whole reason for the class)
-(void) layoutSubviews {
[super layoutSubviews];
// Look for the first next responder that is a UIViewController
UIViewController *ourViewController = nil;
id myNextResponder = [self nextResponder];
while (myNextResponder != nil && ourViewController == nil) {
if ([myNextResponder isKindOfClass:[UIViewController class]]) {
ourViewController = myNextResponder;
}
else {
myNextResponder = [myNextResponder nextResponder];
}
}
// If we got a view controller, then see if it supports the reactToLayout method
if (ourViewController != nil) {
if ([ourViewController respondsToSelector:@selector(reactToLayout)]) {
// Invoke the view controller's reactToLayout method
[ourViewController reactToLayout];
}
}
}
@end
YourViewController.h
#import <UIKit/UIKit.h>
@interface YourViewController : UIViewController {
CGRect lastLayedOutFrame;
UIInterfaceOrientation lastLayedOutOrientation;
}
#pragma mark -
#pragma mark Instance Methods
-(id) init;
-(void) reactToLayout;
@end
YourViewController.m
#import "YourViewController.m"
#pragma mark Private Interface Category
@interface YourViewController()
-(void) setViewForCurrentFrameAndRequestedOrientation:(UIInterfaceOrientation) interfaceOrientation;
@end
@implementation YourPadViewController
-(id) init {
// First our super then set ourselves up
if (self = [super initWithNibName:@"YourViewController" bundle:nil]) {
// Initialize some basic stuff
lastLayedOutFrame = CGRectZero;
lastLayedOutOrientation = UIDeviceOrientationUnknown;
}
return self;
}
-(void) viewWillAppear:(BOOL) animated {
[super viewWillAppear:animated];
// Make sure we're showing the right stuff in the right place
[self setViewForCurrentFrameAndRequestedOrientation:UIDeviceOrientationUnknown];
}
-(void) viewDidAppear:(BOOL) animated {
[super viewDidAppear:animated];
// Make sure we're showing the right stuff in the right place
[self setViewForCurrentFrameAndRequestedOrientation:UIDeviceOrientationUnknown];
}
-(void) reactToLayout {
// Make sure we're showing the right stuff in the right place
[self setViewForCurrentFrameAndRequestedOrientation:UIDeviceOrientationUnknown];
}
#pragma mark -
#pragma mark Rotation Support
-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
return YES;
}
// This is called right before the actual rotation
-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval) duration {
[super willAnimateRotationToInterfaceOrientation:interfaceOrientation duration:duration];
// Make sure we're showing the right stuff in the right place
[self setViewForCurrentFrameAndRequestedOrientation:interfaceOrientation];
}
// Make the necessary adjustments for the different view orientations
-(void) setViewForCurrentFrameAndRequestedOrientation:(UIInterfaceOrientation) interfaceOrientation {
// Set up the requested orientation (need this to handle the Unknown case)
UIInterfaceOrientation requestedOrientation;
if (interfaceOrientation != UIDeviceOrientationUnknown) {
requestedOrientation = interfaceOrientation;
}
else {
requestedOrientation = [[UIDevice currentDevice] orientation];
}
// See if we have anything to do
if (!(CGRectEqualToRect(self.view.frame, lastLayedOutFrame) && lastLayedOutOrientation == requestedOrientation)) {
// Do whatever needs to be done
// Record our last layed out frame and orientation
lastLayedOutFrame = self.view.frame;
lastLayedOutOrientation = requestedOrientation;
}
}
Puedes por favor elaborar? Los límites también son idénticos {320, 460} en ambos casos y el centro tampoco cambia. – user130444
Si está preguntando por qué no se cambia el tamaño del cuadro, ¿los resortes y puntales están configurados correctamente? Eso es lo primero que debes verificar. –
Sí y mi vista cambia el tamaño correctamente cuando se gira. El único problema es cuando se crea mientras está en Paisaje. – user130444