15

初めてのアプリをアプリ ストアに提出しました (承認されました! )。私は今、より大きなiPhone 5画面で動作するように(見栄えが良くなるように)更新したいと考えています。画面を大きくするためにレイアウトを少し変更する以外、何も変更するつもりはありません。

注: 現在の xib を引き伸ばしたくありません。

2 つの xib ファイルを作成し (つまり、メイン画面用に現在の xib ファイルをコピー)、両方をビュー コントローラーにフックして、アプリの起動時に iPhone 5 画面があるかどうかをアプリが検出するようにすることは可能ですか?以前の画面。次に、デバイスに応じて、別の画面をユーザーに表示します。

基になるアプリは同じままにするつもりです。私が望むのは、新しいレイアウトのためにいくつかのボタン/アイテムを移動させて、iPhone 5 ユーザー向けに少し異なる (より高い) 画面を表示することだけです。それ以外の場合は、インターフェイスから何かを追加または削除することはありません。

This SO question/answerは、iPhone または iPad ビューを切り替える方法を示しています。これもそうです。どちらも役に立ちますが、ユーザーが画面の大きい iPhone 5 または iPhone 4S 以下を使用している状況でこれを変更する方法がわかりません。また、2 つのビュー コントローラーを想定しています。ビューコントローラーのロジックはまったく変更されないため、ビューコントローラーは1つだけ必要です。画面上のオブジェクトの配置のみが変更され、それはすべてXIBで行われます。

ビューコントローラーのiteslfが実行中のデバイスを評価し、適切なxibを提示するという答えが必要だと思いますか? はい?いいえ?

もしそうなら、どうすればいいですか?

4

3 に答える 3

25

[完全な回答で改訂: 2012 年 10 月 7 日]

かなりの調査の後、一部はこの SO ページ (アプリが実行されている iPhone のバージョンを検出する方法を示します)で、一部はこの SO ページ (2 つの xib で同じ 'File's Owner' を共有する方法を示す) で答えを見つけました。The Big Nerd Ranch の優れた iOS Programming text の第 10 章で見つけたパズルのピース (loadNibNamed: メソッドを介して個別の xib をロードする) . 方法は次のとおりです。

  1. 2 番目の xib を作成します (File、New...、File、[User Interface] を選択し、[Empty] を選択して保存します。これにより、新しい xib が作成されます。以下の例では、私の従来の xib (3.5 インチ iPhone 用) に名前が付けられています)。 TipMainViewController.xib. 新しい iPhone 5 xib を「TipMainViewController-5.xib」という名前で保存しました

  2. その新しいxibの「ファイルの所有者」を既存のxibと同じViewControllerにします。これを行うには、新しい xib ファイルで [ファイルの所有者] を選択します。次に、'Identity Inspector' で、既存の View Controller をカスタム クラスとして選択します。私の場合、「TipMainViewController」を選択しました。

  3. 新しい UIView を新しい xib の空のキャンバスにドラッグします。新しい UIView の属性インスペクタで、'Size' 属性を 'Retina 4 Full Screen' に設定します。

  4. 既存の「Classic」3.5" xib のすべてのコンテンツを選択します。たとえば、すべてのコントロール、ボタン、セレクター、ラベルなどを選択します。それらをコピーして、新しい iPhone 5 xib に貼り付けます。サイズ変更/移動などを行って、iPhone 用に最適化します。 4インチディスプレイ。

  5. 元のxibを作成したときと同じように、ファイルの所有者との間ですべての接続を確立します。

  6. 最後に、「単一の」ViewController の「viewDidLoad」メソッドで、次のロジックを挿入します (もちろん nib/xib 名を使用します)。

    - (void)loadView
    {
        [super viewDidLoad];
        if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
        {
            CGSize result = [[UIScreen mainScreen] bounds].size;
            if(result.height == 480)
            {
              // iPhone Classic
              [[NSBundle mainBundle] loadNibNamed:@"TipMainViewController" owner:self options:nil];
            }
            if(result.height == 568)
            {
              // iPhone 5
              [[NSBundle mainBundle] loadNibNamed:@"TipMainViewController-5" owner:self options:nil];
            }
        }
    }
    
于 2012-10-01T23:19:20.160 に答える
7

これは、iPhone 5 および iPhone 5より前の iPhone/iPod でロードする方法を示す、View Controller の簡単で実用的なコード サンプルです。myXib-5.xibmyXib.xib

- (void)loadView
{
    if([[UIScreen mainScreen] bounds].size.height == 568)
    {
        // iPhone 5
        self.view = [[NSBundle mainBundle] loadNibNamed:@"myXib-5" owner:self options:nil][0];
    }
    else
    {
        self.view = [[NSBundle mainBundle] loadNibNamed:@"myXib" owner:self options:nil][0];
    }
}

簡単にするために、iPad ではなく iPhone のみをターゲットにしていると想定しています。

XIB のファイル所有者のクラス プロパティも、 を含むビュー コントローラーに設定する必要がありますloadView

于 2013-02-02T01:05:20.667 に答える
6

答えのコードは役に立ちましたが、ユニバーサルアプリ(iphone / ipad)に適したものが必要でした。

他の誰かが同じことを必要とする場合に備えて、ここにあなたが始めるための何かがあります。

同じ名前のxibsを持つViewControllerのiOSのnib/xib命名基準を使用してユニバーサルアプリを構築したとします。

名前を指定しない場合にxibsを自動ロードするための2つの組み込みデフォルトは、initWithNibNameに渡されます。

  • ExampleViewController.xib[クラシックレイアウトのiphone4/4sなどのRetina3.5フルスクリーンでペン先の名前が空の場合のiphoneのデフォルト...]
  • ExampleViewController〜ipad.xib[ペン先が空の場合のipad/ipadminiのデフォルト]

ここで、Retina4フルスクリーンオプションを使用してIBのiphone5 / 5sにカスタムxibsが必要であるとしましょう。つまり、どの568hデバイスでも3.5xibsを表示したくないとします。

カテゴリアプローチを使用したカスタム命名規則は次のとおりです。

  • ExampleViewController-568h.xib [Retina 4フルスクリーン(568h)のペン先名が空の場合のiphoneの非デフォルト/カスタム命名規則]

組み込みの名前付けのデフォルトをオーバーライドする代わりに、カテゴリを使用して、コントローラーに適切なxibを設定します。

https://gist.github.com/scottvrosenthal/4945884

ExampleViewController.m

#import "UIViewController+AppCategories.h"

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    nibNameOrNil = [UIViewController nibNamedForDevice:@"ExampleViewController"];

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

       // Do any additional customization 

    }

    return self;
}

UIViewController + AppCategories.h

#import <UIKit/UIKit.h>

@interface UIViewController (AppCategories)

   + (NSString*)nibNamedForDevice:(NSString*)name;

@end

UIViewController + AppCategories.m

// ExampleViewController.xib [iphone default when nib named empty for Retina 3.5 Full Screen]
// ExampleViewController-568h.xib [iphone custom naming convention when nib named empty for Retina 4 Full Screen (568h)]
// ExampleViewController~ipad.xib [ipad/ipad mini default when nib named empty]

#import "UIViewController+AppCategories.h"

@implementation UIViewController (AppCategories)

+ (NSString*)nibNamedForDevice:(NSString*)name
{

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        if ([UIScreen mainScreen].bounds.size.height == 568)
        {
            //Check if there's a path extension or not
            if (name.pathExtension.length) {
                name = [name stringByReplacingOccurrencesOfString: [NSString stringWithFormat:@".%@", name.pathExtension] withString: [NSString stringWithFormat:@"-568h.%@", name.pathExtension ]
                ];

            } else {
                name = [name stringByAppendingString:@"-568h"];
            }

            // if 568h nib is found
            NSString *nibExists = [[NSBundle mainBundle] pathForResource:name ofType:@"nib"];
            if (nibExists) {
                return name;
           }

        }
    }

    // just default to ios universal app naming convention for xibs
    return Nil;
}

@end
于 2013-02-13T17:28:29.737 に答える