2

これについて多くの投稿があることは知っていますが、まだ問題があります。私がやろうとしていることの擬似コードは次のとおりです。

if(device is running iOS 5 or up)

    @interface RootViewController : UIViewController <UIPageViewControllerDelegate, UIGestureRecognizerDelegate>

    @property (strong, nonatomic) UIPageViewController *pageViewController;

else

    @interface RootViewController : UIViewController <LeavesViewDelegate, UIGestureRecognizerDelegate>

    @property (strong, nonatomic) LeavesViewController *leavesViewController;

endif

ヘッダー ファイルにあるため、プリプロセッサ マクロ チェックを使用する必要があると考えるのは正しいですか? これは、iOS 5 以降の場合 (したがって UIPageViewController がある場合) UIPageViewController を使用するブック アプリです。それ以外の場合は、Leaves (https://github.com/brow/leaves) にフォールバックします。すべてのコードを設定しました。どちらを使用するかをコンパイラに伝える方法を知る必要があります。両方ではなく、UIPageViewController または Leaves のいずれかのプロトコル メソッドのみが必要なので、実行時チェックを使用しても機能しないと思います。また、完全に別個のソース ファイルを使用したくありません。これらのチェックを使用してみました:

#ifdef kCFCoreFoundationVersionNumber_xxx

#ifdef __IPHONE_xxx

#if __IPHONE_OS_VERSION_MAX_ALLOWED <__IPHONE_xxx

(さまざまな xxx を含む)

ここで何が欠けていますか?

編集:

デフォルトの .pch でもこれに気付きました。

#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif

同じテストが私の .h ファイルで機能しなかったのはなぜだろうか?

4

2 に答える 2

0

プリプロセッサ マクロはコンパイル時に処理されるため、これを行うことはできません。Mac でコンパイルしていて、全員が iPhone でコンパイルしているわけではないのに、どの iOS をターゲットにしているのか、コンパイラーはどのように知る必要があるのでしょうか?

実行時にコードを簡単に切り替えることはできません。可能性はありますが、あなたが望んでいるようなものではないと思います。

メソッドが特定の SDK から利用可能かどうかを実行時に確認できます。これははるかに単純で簡単です。しかし、それでは目標を達成することはできません。

私が提案するのは、特定のデリゲート プロトコルが含まれていないスーパークラスを作成することです。そこにすべてのコードを記述し、共有したいとします。

次に、上位のスーパークラスから 2 つのサブクラスを作成します。各クラスに特定のコードを入れます。

以上です。これはあるべき姿です。

于 2012-04-20T06:55:58.003 に答える
0

コメントで述べたように、コンパイル時にこれを行うことはできません。

しかし、ここにあなたのためのアイデアがあります: と のメソッド名が交差しないように見えるUIPageViewControllerDelegateのでLeavesViewDelegate、ヘッダーファイルに次を追加することができます:

-(void) leavesView:(LeavesView*)leavesView willTurnToPageAtIndex:(NSUInteger)pageIndex;
-(void) leavesView:(LeavesView*)leavesView didTurnToPageAtIndex:(NSUInteger)pageIndex;
-(void) pageViewController:(UIPageViewController*)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray*)previousViewControllers transitionCompleted:(BOOL)completed;
-(UIPageViewControllerSpineLocation) pageViewController:(UIPageViewController*)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation;

ヘッダー ファイルでデリゲート プロトコルを明示的に採用しないでください ( 内のデリゲートを省略します< >)。

これら 2 つに使用しているクラスは、次の行に沿った条件で *.m ファイルでインスタンス化できます。

// check for existence of class to determine which controller to instantiate
if(NSClassFromString(@"UIPageViewController"))
{
    // do something and set UIPageViewController delegate to "self"
}
else
{
    // do something else and set LeavesViewController delegate to "self"
}

最後に、これをコンパイルするには、使用するすべてLeavesViewControllerUIPageViewController関連クラスを前方宣言し、一部のフレームワークでは弱いリンクを使用する必要があります。

私はまだ Apple のUIPageViewControllerクラスとプロトコルを使用したことがないので、これ以上の洞察を提供することはできません。何か問題が発生した場合は、必ずお知らせください:)

于 2012-04-20T07:19:24.520 に答える