web-dev-qa-db-ja.com

UIWindowに追加されたUIViewの方向

ユーザーがUITableViewCellのボタンをタップし、関連する画像をズームするコアアニメーションを使用して行う画像のズームイン/アウト効果をサポートするために、デバイス全体(UIWindow)をカバーすることになっているUIViewがあります。

ズームは問題なく実行されていますが、デバイスが横向きであってもサブビューがポートレートモードのままである理由はわかりません。以下の図:

enter image description here

Navigation Controllerはありますが、このビューはUIWindowに直接追加されています。

44
Ken

ここで考えられる原因のいくつかについて読むことができます:
技術的なQ&A QA1688-UIViewControllerがデバイスと共に回転しないのはなぜですか?

あなたの状況では、おそらくウィンドウに別のサブビューとしてビューを追加しているという事実です。最初のサブビューのみが回転イベントを取得します。できることは、最初のウィンドウサブビューのサブビューとして追加することです。

UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window) 
    window = [[UIApplication sharedApplication].windows objectAtIndex:0];
[[[window subviews] objectAtIndex:0] addSubview:myView];    
121
dizy

問題

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

83
hfossli

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];
4
Jon

これは、前述したように、ビューが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
}

また、向きが変わるたびに、ビューの向きも変わります。

1
Oscar Gomez

ビューがウィンドウに直接追加されるという同様の問題がありました。多分これが役立つでしょう: ウィンドウに追加した後にUIViewを自動的にサイジングする

0

この問題を解決した別の解決策。

現在の方向を定義します。

@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
    }
}
0
Antoine