1

デバイスの向きを設定してUIViewを非同期に更新する問題に直面しています。以下のようにviewDidloadにデバイスの向きを実装しました

- (void)viewDidLoad{
[super viewDidLoad];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged) name:UIDeviceOrientationDidChangeNotification object:nil];
[self initialize];}

orientationChanged メソッドには、次のコードがあります

-(void)orientationChanged {
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;

if(UIInterfaceOrientationIsLandscape(orientation)){
    UINib *nib = [UINib nibWithNibName:@"ConsoleViewControllerLandscape" bundle:nil];
    UIView *portraitView = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
    self.view = portraitView;

    [self initialize];

} else {
    UINib *nib = [UINib nibWithNibName:@"ConsoleViewController" bundle:nil];
    UIView *portraitView = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
    self.view = portraitView;

    [self initialize];

}

初期化メソッドでは、実際に次のようなコードで UI を非同期に更新します

 [self performSelectorOnMainThread:@selector(arrangeAsynchronously) withObject:nil waitUntilDone:NO];
- (void) arrangeAsynchronously{
    //Some complex calculation and finally
[self.view addSubview:imageview];
}

問題は、向きが変更された imageViews がメイン ビューに追加されない場合です。縦向きビューから始めて、すべてのイメージビューを縦向きビューで見ることができ、横向きに変更するとビューが空白になるとしましょう。ポートレートに切り替えると、すべてのサブビュー、つまり imageViews が適切に追加されます。問題は、方向が変更されたときです。新しい nib ファイルをロードしていますが、コードはまだ古い nob ファイルからロードされた古いビューを参照しています。参照を変更するにはどうすればよいですか。この問題は、非同期モードで実行した場合にのみ発生します。

デバイスの回転後のサブビュー位置の計算ではなく、uiview の問題ではありません。以前の私のコードは

CGAffineTransform inverseTransform = CGAffineTransformInvert(self.view.transform);
fixedPoint = CGPointApplyAffineTransform(fixedPoint,inverseTransform);
fixedPoint = CGPointMake(fixedPoint.x+126, fixedPoint.y-109);

そして、私はそれをに変更しました

fixedPoint = CGPointMake(fixedPoint.x+126, fixedPoint.y-109);

しかし、なぜ affinetransform が waitUntilDone:NO で動作せず、waitUntilDone:YES で動作するのか、まだわかりません。

4

1 に答える 1

0

あなたの戦略には少し問題があります。self.view新しい を作成したからといってUIView、表示されたウィンドウで置き換えられるわけではありません。

メインUIView(ここで置き換えるもの) にコンテナー ビューを追加し、デバイスの向きが変更されたときにコンテナー ビューの内容を変更することをお勧めします。

編集

私の答えは少し不明確に思えるかもしれませんので、もっと詳しく説明してみましょう。aのはUIViewaUIViewControllerによって提示されますUIWindow。これは、ウィンドウがビューへの参照を持っていることを意味します。(新しい を構築することによって)UIViewのを変更しても、 に反映されるわけではありません。UIViewControllerUIViewUIWindow


初期シナリオ:

UIViewController-> UIView1 <-UIWindow

新しい UIView を構築した後:

UIViewController-> UIView2
UIWindow-> UIView1


上の図からわかるように、エラーは発生していませんが、2 つのビューがあり、変更がUIViewController画面に反映されていません。

ただし、初めて機能することは幸運かもしれません: UIView UIWindow によって提示される BEFORE を再構築すると、すべてがまだ機能しますが、それでもまだ悪い設計であり、簡単に壊れる可能性があります (タイミングが変更された後に見られるように) )。

これは、実際に機能する可能性がある場合です。


初期シナリオ:

*UIViewController-> UIView1

新しい UIView を構築した後:

*UIViewController-> UIView2

ウィンドウは画面にビューを表示します:

UIViewController-> UIView2 <-UIWindow


基本的に、提示されUIViewた後はハンドルを の に捨てないでください。UIViewController

これが、参照/ポインターの仕組みを理解するのに役立つことを願っています。

于 2012-07-01T10:36:42.630 に答える