0

私はobjective-Cが初めてなので、ご容赦ください。Xcode4 の Universal App テンプレートから始めて、アプリケーションを構築しました。私が固執しようとしたテンプレートがあなたを始めるという慣習があります. ビュー コントローラーごとに、デバイスの種類ごとにメイン ファイルとサブクラスがあります。例えば:

Project/
    ExampleViewController.(h|m)
    - iPhone/
      - ExampleViewController_iPhone.(h|m|xib)
    - iPad/
      - ExampleViewController_iPad.(h|m|xib)

ほとんどの場合、これは非常に便利です。ほとんどのロジックはスーパークラスに入り、サブクラスはデバイス固有の実装を処理します。

ここが私が得られない部分です。デバイスごとに異なる xib をロードする必要があるという理由だけで、各サブクラスで同じことを行うコードがある場合があります。例えば:

ExampleViewController_iPhone

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
    ContentDetailViewController_iPhone *detailViewController = [[ContentDetailViewController_iPhone alloc] init];
    detailViewController.content = selectedContent;
    detailViewController.managedObjectContext = self.managedObjectContext;

    [self.navigationController pushViewController:detailViewController animated:YES];
    [detailViewController release];
}

ExampleViewController_iPad

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
    ContentDetailViewController_iPad *detailViewController = [[ContentDetailViewController_iPad alloc] init];
    detailViewController.content = selectedContent;
    detailViewController.managedObjectContext = self.managedObjectContext;

    [self.navigationController pushViewController:detailViewController animated:YES];
    [detailViewController release];
}

_iPad... 2 番目のインスタンスでは、View Controller のバージョンをロードしていることだけが異なることに注意してください。これは、ビュー コントローラiPadiPhoneビュー コントローラが別々のデバイス固有のペン先に接続されているために必要です。

これを行うための「正しい」パターンは何ですか?


アップデート

デバイス修飾子を使用して個別のxibをロードすることに関するこの回答を見つけました。これは、1つのデバイスに特定のサブクラスが必要ない場合に役立つようですが、特定の_iPhoneまたは_iPadインスタンスをインスタンス化する必要がある場合はそれでも役に立ちませんデバイス固有の機能用のビュー コントローラー。

4

1 に答える 1

1

問題を解決するには、2 つの簡単な方法があります。スーパークラスに配置すると、どちらも機能します。

最初の方法が機能するのは、2 つの異なるクラスがあり、どちらが作成されるかは、使用しているデバイスによって異なります。デバイス固有のコードがないため、異なるクラスを使用しないと機能しません。オブジェクトにそのクラスを尋ねて、それがどちらであるかを決定する必要があります。オブジェクトのクラスはデバイス固有のクラスになるため、スーパークラスから要求された場合でも、どのクラスが作成されたかを確認して対応できます。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
    Class classToUse;
    if([self class] == [ExampleViewController_iPad class]) {
        // We are running on the iPad
        classToUse = [ContentDetailViewController_iPad class];
    } else {
        // We must be running on either the iPhone or iPod touch
        classToUse = [ContentDetailViewController_iPhone class];
    }
    // Just use superclass for typing here, since we aren't doing anything device specific
    ContentDetailViewController *detailViewController = [[classToUse alloc] init];
    detailViewController.content = selectedContent;
    detailViewController.managedObjectContext = self.managedObjectContext;

    [self.navigationController pushViewController:detailViewController animated:YES];
    [detailViewController release];
}

2 番目の方法は、プログラムのどの場所でも機能します。Apple は、iOS 3.2 の UIDevice クラスに「ユーザー インターフェイス イディオム」と呼ばれるプロパティを追加しました。現在、可能な値はUIUserInterfaceIdiomPadとの 2 つUIUserInterfaceIdiomPhoneです。これらは 3.2 より前のバージョンには存在しないため、Apple はUIUserInterfaceIdiomPhone、バージョンが 3.2 未満の場合に戻り、3.2 以上の場合に UIDevice オブジェクトから実際の値を取得するマクロも追加しました。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
    Class classToUse;
    // If you aren't supporting versions prior to 3.2, you can use [UIDevice currentDevice].userInterfaceIdiom instead to save a couple of cycles
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        // We are running on the iPad
        classToUse = [ContentDetailViewController_iPad class];
    } else {
        // We must be running on either the iPhone or iPod touch
        classToUse = [ContentDetailViewController_iPhone class];
    }
    // Just use superclass for typing here, since we aren't doing anything device specific
    ContentDetailViewController *detailViewController = [[classToUse alloc] init];
    detailViewController.content = selectedContent;
    detailViewController.managedObjectContext = self.managedObjectContext;

    [self.navigationController pushViewController:detailViewController animated:YES];
    [detailViewController release];
}
于 2011-04-12T04:45:00.477 に答える