ユーザーがUITableViewCellのボタンをタップし、関連する画像をズームするコアアニメーションを使用して行う画像のズームイン/アウト効果をサポートするために、デバイス全体(UIWindow)をカバーすることになっているUIViewがあります。
ズームは問題なく実行されていますが、デバイスが横向きであってもサブビューがポートレートモードのままである理由はわかりません。以下の図:
Navigation Controllerはありますが、このビューはUIWindowに直接追加されています。
ここで考えられる原因のいくつかについて読むことができます:
技術的なQ&A QA1688-UIViewControllerがデバイスと共に回転しないのはなぜですか?
あなたの状況では、おそらくウィンドウに別のサブビューとしてビューを追加しているという事実です。最初のサブビューのみが回転イベントを取得します。できることは、最初のウィンドウサブビューのサブビューとして追加することです。
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window)
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
[[[window subviews] objectAtIndex:0] addSubview:myView];
IOS 6以降では、最上位のView Controllerのみ(UIApplicationオブジェクトと共に)、デバイスの向きの変更に応じて回転するかどうかの決定に参加します。
https://developer.Apple.com/library/content/qa/qa1688/_index.html
AGWindowView という名前のポッドをオープンソース化しました。
回転やフレームの変更を自動的に処理するため、心配する必要はありません。
SDKとiOSシステムバージョンの任意の組み合わせをサポートします。関連するコードはここにあります: https://github.com/hfossli/AGWindowView/blob/master/Source/AGWindowView.m
KeyWindowの最初のサブビューを取得するためのヘルパープロパティとメソッドを持つUIApplicationにカテゴリを作成しました。これは、とにかくオーバーレイしたいビューです。 UIViewControllerによって管理されるビューをそのビューに追加すると、shouldRotateToInterfaceOrientation:メソッドが呼び出されます。
UIApplication + WindowOverlay.h
#import <UIKit/UIKit.h>
@interface UIApplication(WindowOverlay)
@property (nonatomic, readonly) UIView *baseWindowView;
-(void)addWindowOverlay:(UIView *)view;
@end
UIApplication + WindowOverlay.m
#import "UIApplication+WindowOverlay.h"
@implementation UIApplication(WindowOverlay)
-(UIView *)baseWindowView{
if (self.keyWindow.subviews.count > 0){
return [self.keyWindow.subviews objectAtIndex:0];
}
return nil;
}
-(void)addWindowOverlay:(UIView *)view{
[self.baseWindowView addSubview:view];
}
@end
そして、これがあなたの使い方です。
//at the top of the file...or in {yourproject}.pch
#import "UIApplication+WindowOverlay.h
//in a method:
UIView *view = [UIView new];
UIView *window = [UIApplication sharedApplication].baseWindowView;
view.frame = window.bounds;
[window addSubview:view];
//or
[[UIApplication sharedApplication] addWindowOverlay:view];
これは、前述したように、ビューがUIWindowに直接追加されているため、Navigation Controllerに対して回転するメソッドが呼び出された場合、uiviewには何も起こりません。 UIViewは、View Controllerビューのサブビューである場合に回転します。何らかの理由でこれができない場合。次に、このメソッドをオーバーライドできます。
// This method is called every time the device changes orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
}
また、向きが変わるたびに、ビューの向きも変わります。
ビューがウィンドウに直接追加されるという同様の問題がありました。多分これが役立つでしょう: ウィンドウに追加した後にUIViewを自動的にサイジングする
この問題を解決した別の解決策。
現在の方向を定義します。
@interface AJImageCollectionViewController (){
UIInterfaceOrientation _currentOrientation;
}
@end
次に、viewWillLayoutSubviewsで方向を確認します。
- (void)viewWillLayoutSubviews {
[self checkIfOrientationChanged];
}
- (void)checkIfOrientationChanged {
UIInterfaceOrientation newOrientation = [[UIApplication sharedApplication] statusBarOrientation];
BOOL newOrientationIsPortrait = UIInterfaceOrientationIsPortrait(newOrientation);
BOOL oldOrientationIsPortrait = UIInterfaceOrientationIsPortrait(_currentOrientation);
// Check if the orientation is the same as the current
if(newOrientationIsPortrait != oldOrientationIsPortrait){
_currentOrientation = newOrientation;
// Do some stuff with the new orientation
}
}