3

だから、私はiPad用のiOSアプリを構築しています。アプリにはビデオチャットが組み込まれています。ビデオチャット、通知などはすべて機能しています。私の問題はインターフェースにあります。iOSプログラミングに関しては、私は初心者です。私はこれを2週間前に始めたばかりです。投稿が少し長い場合は申し訳ありませんが、ここで関係している可能性のあるすべてのものと私の思考プロセスを強調しようとしました. どんな批評でも大歓迎です。

ほとんどの情報を表示する UIWebView (webView と呼びます) があります。ボタンをクリックすると、サイズが変更され、小さな新しいビューが表示されます。このビューには、チャット相手 (imageOne と呼びます)、ビデオ チャット (imageTwo と呼びます)、ハングの 3 つの項目があります。アップボタン (buttonHangUp と呼びます)。デバイスが横向きの場合、新しいビューを右側に表示し、imageOne、imageTwo、buttonHangUp を垂直に配置します。デバイスが縦向きの場合、新しいビューを下部に表示し、imageOne、image Two、buttonHangUp を水平に配置します。

ここに私の思考プロセスがどのように進んだかがあります:

私は 2 番目のオプションに進みました (これを行うためのより簡単な方法がある場合、または何か他のことを行うべきだった場合は、お知らせください。取引のヒントとコツを学びたいと思います)。

これが私のコードの行き方です:

  • そこにグローバル変数 isLandscape a la apple tutorial を作成しました
  • 他に 6 つのグローバル変数 CGRects を作成し、それぞれが縦向きと横向き (imageOnePortrait、imageOneLandscape など) のさまざまなアイテムの位置を保持します。
  • 私はawakeFromNibを実装し、ポートレート変数をアイテムの初期位置とサイズに設定しました

    (void) awakeFromNib
    {
    isLandscape = NO;
    
    imageOnePortrait = self.imageOne.frame;
    imageTwoPortrait = self.imageTwo.frame;
    buttonHangUpPortrait = self.buttonHangUp.frame;
    
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
    }
    
  • アップルのドキュメントで説明されているように、orientationChanged メソッドを実装しました。ただし、UIDeviceOrientation は探していた横向き/縦向きの向きではなく、フェイスアップとフェイスダウンのメッセージを送信していたため、UIDeviceOrientation を UIInterfaceOrientation に置き換えました。

    - (void) orientationChanged:(NSNotification *)notification
    {
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
    if(UIInterfaceOrientationIsLandscape(interfaceOrientation) && !isLandscape)
    {
        CGRect temp = self.videoView.frame;
        temp.size.width = 360;
        temp.size.height = 748;
        temp.origin.x = 664;
        temp.origin.y = 0;
        self.videoView.frame = temp;
        self.imageOne.frame = imageOneLandscape;
        self.imageTwo.frame = imageTwoLandscape;
        self.buttonHangUp.frame = buttonHangUpLandscape;
        isLandscape = YES;
    }
    else if (UIInterfaceOrientationIsPortrait(interfaceOrientation) && isLandscape)
    {
        CGRect temp = self.videoView.frame;
        temp.size.width = 768;
        temp.size.height = 300;
        temp.origin.x = 0;
        temp.origin.y = 703;
        self.videoView.frame = temp;
        self.imageTwo.frame = imageTwoPortrait;
        self.imageOne.frame = imageOnePortrait;
        self.buttonHangUp.frame = buttonHangUpPortrait;
        isLandscape = NO;
    }
    }
    
  • viewDidLoad の下で、Landscape 座標の座標を設定します (これらの座標は、orientationMade 関数の呼び出しが行われる前に読み込まれ、videoView に対して相対的であると想定しています。何かに対して相対的に設定する必要がある場合は、修正してくださいelse; ストーリーボードの videoView に関連して設定されていることがわかります):

    imageOneLandscape.origin.x = 20;
    imageOneLandscape.origin.y = 20;
    imageTwoLandscape.origin.x = 20;
    imageTwoLandscape.origin.y = 288;
    buttonHangUpLandscape.origin.x = 20;
    buttonHangUpLandscape.origin.y = 556;
    
  • ビデオ コールを開始する関数の下で、webView のサイズを変更し、videoView を表示します。

    CGRect temp = self.webView.frame;
    
    if(isLandscape)
    {
        temp.size.width -= self.videoView.frame.size.width;
        temp.origin.x = 0;
        temp.origin.y = 0;
        self.webView.frame = temp;
    } else {
        temp.size.height -= self.videoView.frame.size.height;
        temp.origin.x = 0;
        temp.origin.y = 0;
        self.webView.frame = temp;
    }
    
    self.videoView.hidden = FALSE;
    
  • 次に、buttonHangUp 関数で反対のことを行います

いくつかの間違ったことが起こっています:

  • 向きを切り替えると、videoView が常に移動またはサイズ変更されるとは限らず、移動すると移動が遅れることがよくあります (残りのアイテムが回転してから 1 秒後に発生します)。
  • ランドスケープに切り替えると、imageOne と imageTwo が水平方向に押しつぶされ、設定した位置に配置されません。
  • ポートレートに切り替えると、常に問題なく動作しているように見えます。videoView は常に適切な場所に移動し、そのサブビュー (imageOne、imageTwo、および buttonHangUp) も同様に移動します。
  • 向きを変えずにiPadを平らに置くと、imageOneとimageTwoが縦向きビューから消えます
  • ビューをviewDidLoadで別のレイアウトで表示するように設定しても、ストーリーボードにあるレイアウトにリセットされます

ここで何が起こっているのか、なぜそれが起こっているのか、誰か説明してもらえますか? これは私を非常に混乱させます。webView とアプリ自体の座標間の座標系の切り替え、実行中のさまざまな関数の優先順位 (awakeFromNib、ストーリーボードから初めて設定されるビュー座標、viewDidLoad など) に関係していると思います。サブビューの再描画、またはこれらすべての問題の組み合わせと、場合によってはさらに多くの問題があります。これらの問題については、次に調査します。

また、私が望むものを達成するためのベストプラクティスについて誰かが言及してくれれば幸いです。私がこれに慣れていないと言ったように、残念ながらアップルのドキュメントには、私の場合のベストプラクティスと見なされるものは含まれていません。記事へのリンクも歓迎します。

4

2 に答える 2

1

非常に長い質問がありますが、デバイスの向きが正しく機能しない理由を説明します。

通知を生成するオブジェクトを指定していません。

これを変える:

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

これに:

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

また、通知センターの力を利用していないことに注意することも重要です。あなたは余分な仕事をしていて、通知内で送信された実際の向きを取得していません。毎回 UIInterfaceOrientation を確認する必要はありません。次のようにメモからデバイスの向きを取得できます。

- (void) orientationChanged:(NSNotification *)note
{
    UIDevice *device = note.object;
    switch(device.orientation)//do whatever you want in each orientation
    {
        case UIDeviceOrientationPortrait:
            break;
        case UIDeviceOrientationPortraitUpsideDown:
            break;
        case UIDeviceOrientationLandscapeLeft:
            break;
        case UIDeviceOrientationLandscapeRight:
            break;
        default:
            break;
    };
}
于 2013-02-26T20:36:36.020 に答える
0

昨日、数時間デバッグした後、コードを修正しました。以下は、うまくいかなかったすべてのことであり、方向の切り替えをプログラムで処理する方法についての役立つガイドになることを願っています。

  • まず、awakeFromNib に、座標と位置を処理するコードを配置しないでください。awakeFromNib は、ビューの読み込みが開始される前に呼び出されるため、位置については何も知りません。viewDidLoad ですべての座標の初期化を行います。
  • 次に、autolayout を off に設定し、すべてのコンテナー ビューに対して autoresize サブビューを off に設定してください。これはしばらく私をつまずかせました。
  • 3 番目に、ここで説明されているデバイスの向きを呼び出す Apple メソッドを使用します。 SW14 . 上記のステータスバーの向きよりもはるかに信頼性が高いことがわかりました.
  • 第 4 に、これは上記のコードでは間違っていて、私の側のエラーでした。移動する必要があるすべてのコンポーネントのサイズを必ず初期化してください。横向きと縦向きの間を移動するために使用される上記の CGRects には原点が定義されていますが、サイズがないため、それらに設定するとビューが消えていました。
  • 第 5 に、最後に、スライダーが表示/非表示になったときに、横向きと縦向きのグローバル変数の両方に対してサイズ調整を行うようにしてください。 webView.

横向きと縦向きのレイアウトをどのように扱っているかについてのコメントを歓迎します!

于 2013-02-27T19:21:50.640 に答える