Możesz użyć czegoś podobnego UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)
do określenia orientacji, a następnie odpowiednio użyć wymiarów.
JEDNAK, podczas zmiany orientacji jak w UIViewController's
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
Użyj orientacji przekazanej, toInterfaceOrientation
ponieważ statusBarOrientation UIApplication będzie nadal wskazywać na starą orientację, ponieważ jeszcze się nie zmieniła (ponieważ jesteś w module will
obsługi zdarzeń).
Podsumowanie
Istnieje kilka powiązanych z tym postów, ale każdy z nich wydaje się wskazywać, że musisz:
- Spójrz,
[[UIScreen mainScreen] bounds]
aby uzyskać wymiary,
- Sprawdź, w jakiej jesteś orientacji i
- Uwzględnij wysokość paska stanu (jeśli jest pokazana)
Spinki do mankietów
Kodeks roboczy
Zwykle nie posuwam się tak daleko, ale wzbudziłeś moje zainteresowanie. Poniższy kod powinien załatwić sprawę. Napisałem kategorię na UIApplication. Dodałem metody klasowe, aby uzyskać currentSize lub rozmiar w danej orientacji, czyli to, co nazywasz w UIViewController willRotateToInterfaceOrientation:duration:
.
@interface UIApplication (AppDimensions)
+(CGSize) currentSize;
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation;
@end
@implementation UIApplication (AppDimensions)
+(CGSize) currentSize
{
return [UIApplication sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
CGSize size = [UIScreen mainScreen].bounds.size;
UIApplication *application = [UIApplication sharedApplication];
if (UIInterfaceOrientationIsLandscape(orientation))
{
size = CGSizeMake(size.height, size.width);
}
if (application.statusBarHidden == NO)
{
size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
}
return size;
}
@end
Aby skorzystać z kodu wystarczy zadzwonić [UIApplication currentSize]
. Uruchomiłem również powyższy kod, więc wiem, że działa i raportuje prawidłowe odpowiedzi we wszystkich orientacjach. Zwróć uwagę, że uwzględniam pasek stanu. Co ciekawe, musiałem odjąć MIN wysokości i szerokości paska stanu.
Mam nadzieję że to pomoże. :RE
Inne przemyślenia
Możesz przejść do uzyskania wymiarów, patrząc na właściwość UIWindow rootViewController
. Patrzyłem na to w przeszłości i podobnie przedstawia te same wymiary zarówno w orientacji pionowej, jak i poziomej, z wyjątkiem tego, że informuje o przekształceniu rotacyjnym:
(gdb) po [[[[[UIApplication sharedApplication] keyWindow] rootViewController] widok]
<UILayoutContainerView: 0xf7296f0; ramka = (0 0; 320 480); transformacja = [0, -1, 1, 0, 0, 0]; autorezacja = W + H; layer = <CALayer: 0xf729b80 >>
(gdb) po [[[[[UIApplication sharedApplication] keyWindow] rootViewController] widok]
<UILayoutContainerView: 0xf7296f0; ramka = (0 0; 320 480); autorezacja = W + H; layer = <CALayer: 0xf729b80 >>
Nie jestem pewien, jak działa twoja aplikacja, ale jeśli nie używasz jakiegoś kontrolera nawigacyjnego, możesz mieć UIView pod głównym widokiem z maksymalną wysokością / szerokością rodzica i rosnąć / kurczyć się z rodzicem. Następnie można zrobić: [[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame]
. W jednej linii wygląda to dość intensywnie, ale masz pomysł.
Jednak ... Nadal lepiej byłoby wykonać powyższe 3 kroki pod podsumowaniem. Zacznij zadzierać z UIWindows, a dowiesz się dziwnych rzeczy, na przykład pokazanie UIAlertView zmieni okno klucza UIApplication, aby wskazywało na nowe okno UIWindow utworzone przez UIAlertView. Kto wiedział? Zrobiłem to po znalezieniu błędu polegającego na keyWindow i odkryciu, że to się tak zmieniło!
applicationFrame
zamiastbounds
(na UIScreen), nie musisz odejmować wysokości paska stanu.mainScreen().bounds.size
stał się zależny od orientacji od iOS 8 i nowszychTo jest mój kod rozwiązania! Ta metoda może dodać do klasy Categroy klasy NSObject lub możesz zdefiniować niestandardową klasę UIViewController Top i pozwolić wszystkim innym UIViewControllers na dziedziczenie.
Uwaga , po IOS8, jak mówi Apple Document of UIScreen's bounds property :
więc ze względu na kompatybilność powinniśmy wykryć wersję IOS i wprowadzić zmiany jak poniżej:
źródło
Oto przydatne makro:
źródło
W iOS 8+ należy skorzystać z
viewWillTransitionToSize:withTransitionCoordinator
metody:Zastępuje to przestarzałą metodę animacji, która nie podawała żadnych informacji o rozmiarze:
źródło
Od wersji iOS 8 granice ekranu są teraz zwracane prawidłowo dla bieżącej orientacji. Oznacza to, że iPad w orientacji poziomej [UIScreen mainScreen] .bounds zwróciłby 768 na iOS <= 7 i 1024 na iOS 8.
Poniższe zwraca prawidłową wysokość i szerokość we wszystkich wydanych wersjach.
źródło
jeśli chcesz mieć rozmiar zależny od orientacji i masz widok, możesz po prostu użyć:
źródło
Pisałem kategorię
UIScreen
, która działa na wszystkich wersjach iOS, dzięki czemu można go używać tak:[[UIScreen mainScreen] currentScreenSize]
.źródło
Oto szybki sposób na uzyskanie rozmiarów ekranu zależnych od orientacji:
Są to standardowe funkcje mojego projektu:
https://github.com/goktugyil/EZSwiftExtensions
źródło
źródło
Jednak w iOS 8.0.2:
źródło
użyj -> setNeedsDisplay () dla widoku, którego rozmiar chcesz zmienić.
źródło