2010-07-11 24 views
7

Ich habe ein sehr einfaches UIScrollView Beispiel, das einfach nicht tut, was es soll. Nicht sicher, ob es ein Fehler mit der API oder ein Fehler in meinem Code ist.UIScrollView bekommt keine neue Größe bei Orientierungsänderung

Grundsätzlich habe ich eine UIViewController mit einer UIScrollView wie es ist. Wenn ich es zum UIWindow hinzufügen und die Ausrichtung des iPad ändern, logge ich die UIScrollView s Größe aus, die falsch (?) Berichtet wird.

Hier ist meine UIViewController Umsetzung:

@implementation CustomViewController 
- (void)loadView { 
    scrollView = [[[UIScrollView alloc] init] autorelease]; 
    scrollView.delegate = self; 
    scrollView.backgroundColor = [UIColor redColor]; 
    self.view = scrollView; 
} 

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    CGSize rect = scrollView.frame.size; 
    NSLog(@"will rotate w%f h%f", rect.width, rect.height); 
} 

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    CGSize rect = scrollView.frame.size; 
    NSLog(@"will animate rotation w%f h%f", rect.width, rect.height); 
} 

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 
    CGSize rect = scrollView.frame.size; 
    NSLog(@"did rotate w%f h%f", rect.width, rect.height); 
} 

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

@end 

Wenn ich den obigen Code ausführen ich die folgenden Einträge in meiner Konsole sehen:

2010-07-11 11:03:05.214 Untitled2[6682:207] will rotate w768.000000 h1004.000000 
2010-07-11 11:03:05.214 Untitled2[6682:207] will animate rotation w748.000000 h1024.000000 
2010-07-11 11:03:05.619 Untitled2[6682:207] did rotate w748.000000 h1024.000000 
2010-07-11 11:03:07.951 Untitled2[6682:207] will rotate w748.000000 h1024.000000 
2010-07-11 11:03:07.958 Untitled2[6682:207] will animate rotation w768.000000 h1004.000000 
2010-07-11 11:03:08.367 Untitled2[6682:207] did rotate w768.000000 h1004.000000 

Wie Sie die Orientierung Änderungen sehen können, ist die Größe des UIScrollView , aber nur um die neue Statusleiste zu erlauben. Ich würde erwarten, dass die Breite und Höhe drastisch ändern, wie die UIScrollView ist, wie breit es ist hoch und umgekehrt.

Gibt es eine Möglichkeit, die UIScrollView zu erhalten, um ihre tatsächliche Größe zu melden?

Antwort

3

Ich habe die Antwort, wenn Sie noch suchen. Testen Sie die Grenzen, nicht den Rahmen.

Grund: frame ist eine abgeleitete Eigenschaft der Grenzen und die Transformation wird für die Rotation angewendet.

+0

Das funktioniert nicht. Ich nehme eine Änderung ab, dann benutze ich NSStringFromRect (self.bounds) und drucke die Grenzen "kurz vor dem Ändern". Die currentDevice-Ausrichtung gibt jedoch den richtigen Wert zurück. Immerhin gibt es immer dasselbe, aber Mann ... dieses Problem sollte nicht so lange dauern. Aus den Dokumenten, während Grenzen die nicht abgeleitete ist, ist es nicht immer 0,0, genauso wie die Rahmenbreite, genauso wie die Rahmenhöhe? –

+0

Der Ursprung der Grenzen ist standardmäßig immer 0,0, es sei denn, Sie ändern den Teil der Ansicht, den Sie anzeigen möchten. Das ist nur die halbe Geschichte, ein CGRect enthält auch ein Größenelement und das ändert sich normalerweise, wenn Sie die Größe einer Ansicht ändern. Die obigen "Will" -Funktionen geben Ihnen die "Vorher-Werte", die "Did" -Funktionen geben Ihnen die "Nach-Werte". –

2

Die Größe von Ansichten ändert sich nicht automatisch, wenn die Größe der Superviews geändert wird, es sei denn, Sie legen sie ausdrücklich fest. Für diese Scroll-Ansicht müssten Sie ihr sagen, dass sie ihre Breite und Höhe ändern soll, wenn ihre Superansicht dies tut.

scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
+0

Leider eine Redimensionierung Maske nach der Zugabe noch ich die ungültigen Dimensionen wieder kommen bekommen. Optisch ist alles in Ordnung, aber ich kann mich nicht auf die Rahmenmaße verlassen. Ich habe es gehackt, indem ich die Geräteausrichtung erkannt habe und die Breite und Höhe im Querformat gedreht habe - das ist nicht ideal, aber es funktioniert. – d2kagw

+0

Sie müssen auf die [[UIDevice currentDevice] Ausrichtung prüfen] und sehen dies: UIDeviceOrienationIsPortrait() oder ähnlich, um es zu testen. Der Rahmen ist falsch, aber die richtige Ausrichtung wird angezeigt. Es ist nervig, ich habe gerade damit zu tun, aber ich bin froh, dass etwas fest ist. Vielleicht hilft mir die Schranken-Antwort, meine UIScrollView zu skalieren, aber meine ist offkilter, auch wenn ich die Mathematik manuell geändert habe, um sie an die Ausrichtung anzupassen. –

1

Ich habe bemerkt, dass die neuen contentSize in didRotateFromInterfaceOrientation Bestimmung auch unmöglich ist, wenn man anstelle einer dedizierten iPad NIB-Datei mit einer iPhone NIB-Datei beginnen: die Frames in der iPhone-NIB-Datei ist viel kleiner und damit die berechnete Höhe des Inhalts wird viel größer als es sein sollte, wenn Sie tatsächlich auf einem iPad sind. Apple DID sagen, dass ich eine separate iPad NIB-Datei erstellen muss ...

So, ich bekomme auch die alten Dimensionen in didRotateFromInterfaceOrientation, aber für mich ist es jetzt weniger ein Problem, da iOS alles OK behandelt, sobald ich Beginnen Sie mit der richtigen NIB-Datei. Dennoch scheint es mir weniger intuitiv zu sein, dass in der didRotateFromInterfaceOrientation Methode die Rahmenmaße für die aktuelle Ansicht nicht korrekt sind.

PS. Ich habe am Ende eine Lösung gefunden, benutze einfach die Benachrichtigungen anstelle von didRotateFromInterfaceOrientation.

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
     [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(orientationChanged:) 
               name:UIDeviceOrientationDidChangeNotification 
               object:nil]; 

Dann in der orientationChanged Methode, um die Ansichten zu dem neuen Rahmen anzupassen. Ich hatte ein letztes Problem: Wenn die ursprüngliche Ausrichtung von der Ausrichtung in der Spitze abweicht, wäre die Ansicht immer noch falsch, ich habe das gelöst, indem ich eine neue NIB-Datei speziell für die Landschaftsansicht erstellt habe. In der init-Methode wählt die ViewController, welche NIB es basierend auf der aktuellen Ausrichtung lädt.

0

Normalerweise behebe ich das, indem ich einen Wert von contentSize auf 0 wie CGSizeMake(contentSize.width, 0) für horizontale Ansicht setze.

Um UIScrollView zu zwingen, nur z.B. horizontaler nicht scrollbarer Wert für contentSize zu 0>CGSizeMake(contentSize.width, 0).

Ich hoffe es hilft.

0

Ich weiß nicht, es ist Ihnen helfen, weil ich das nie getestet, aber ich denke, dass es hilfreich sein könnte Sie

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
self.view = scrollView; 
CGSize rect = scrollView.frame.size; 
NSLog(@"will rotate w%f h%f", rect.width, rect.height); 
} 

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
self.view = scrollView;  
CGSize rect = scrollView.frame.size; 
NSLog(@"will animate rotation w%f h%f", rect.width, rect.height); 
} 

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 
self.view = scrollView; 
CGSize rect = scrollView.frame.size; 
NSLog(@"did rotate w%f h%f", rect.width, rect.height); 
} 

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