16

私はwebViewベースのアプリを持っていますが、ユーザーがトラックパッドとマジックマウスをスワイプしてアプリをナビゲートできるようにしたいと考えています。したがって、NSPageControllerを実装します。

ドキュメントとPictureSwiperアプリを見てきましたが、これらは実際にはwebView用ではありません。そこで、webViewでNSPageControllerを使用する方法を知りたいと思います。webView前のページと次のページをそれぞれロードする2つのアクションgoBack:とgoForward:として定義されたwebViewがあります。

ただし、NSPageControllerを単純なwebViewで動作させる方法を知りません。それを行う方法はありますが、私には方法がありません。誰かが私がやろうとしていることを説明してくれたら、それは素晴らしいことです。または、特に寛大な気分の場合は、私の無料のブラウザソースの例をダウンロードできます。https://sites.google.com/site/infiniteopensyntax/basic-web-browser

そのソースは、私自身のアプリがどのようにセットアップされているかを示しています。そのアプリにNSPageControllerを実装してソースを送っていただければ幸いです。それほど多くはありませんが、そうする場合は、スワイプの例をInfinite Open Syntaxに追加して、名前を付けます。ライセンスを選択できます。

これはCocoaであり、CocoaTouchではありません

編集

さて、今、私はアプリがまだSnowLeopardで動作することを確認する必要があります。おそらく、コンセントを外すことでこれをテストできます。戻るボタンと進むボタンを除いて、正常に動作します。これを行うために、私はクラスNSPageControllerをチェックすると思います。存在しない場合は、pageControllerの使用をスキップします。

- (IBAction)goBack:(id)sender {
    if (NSClassFromString(@"NSPageController") != Nil)
    {
        [self.pageController navigateBack:sender];
    }
    {

         //Not 10.8
        [webView goBack];
    }
}
4

2 に答える 2

9

リンク先のページのダウンロードリンクが機能しないため、より一般的な回答を残しておきます。

NSPageController;を使用している場合は、複数のWebViewを保持したり、スナップショットを手動で生成したりする必要はありません。それはあなたのためにそれを世話します。あなたの場合、履歴モードNSPageControllerで使用したいと思います。これを行うには、にを配線します。次の3つのメソッドを実装する必要があります。WebViewpageController.viewNSPageControllerDelegate

- (void)pageControllerWillStartLiveTransition:(NSPageController *)pageController;
- (void)pageController:(NSPageController *)pageController didTransitionToObject:(id)object;
- (void)pageControllerDidEndLiveTransition:(NSPageController *)pageController;

WebViewが(戻る/進むアクションではなく)新しいページに移動するたびに、を呼び出しnavigateForwardToObject:(id)objectますpageControllerobjectナビゲートされたページのユーザー状態(スクロール位置、強調表示されたテキスト、フォームの内容など)とページのを格納するカスタムオブジェクトを作成しますWebHistoryItem。ユーザーの状態は最初は未定義にすることができますが、で設定する必要がありますpageControllerWillStartLiveTransition:。次に例を示します。

- (void)pageControllerWillStartLiveTransition:(NSPageController *)pageController
{
  // Remember user state
  MyCustomObject *object = [self.pageController.arrangedObjects objectAtIndex:self.pageController.selectedIndex];
  object.userState = someUserState;
}

そのメソッドが戻ると、pageControllerはそのビュー(WebView)を非表示にし、代わりにそのビューの以前の状態のスナップショットを表示します。

スワイプアニメーションが完了すると、pageController:didTransitionToObject:が呼び出されます。涼しい。そのメソッドで実行する必要があるのは、メソッドを使用してWebViewをそのアイテムから取得し、そのアイテムに戻すことWebHistoryItemです。また、ロードが完了したら復元する必要があるため、(たとえば、インスタンス変数に)保存したユーザー状態を保持する必要があります。objectgoToBackForwardItem:objectWebView

最後に、pageControllerDidEndLiveTransition:WebViewを再表示する前に、やりたいことを何でもします。WebViewの読み込みが完了するまでユーザーの状態は復元されないため、これは何もないと思います。そのため、実装に必要なのはです[pageController completeTransition]

最後の詳細は、戻る/進むボタンです。通常どおりに実装する必要がありますが、navigateBack:またはnavigateForward:pageControllerで呼び出す必要もあります。

それはほとんどそれをカバーしています。私は実際にこの特定の例を試したことがないので、何か問題が発生した場合はお知らせください。

編集

基本的な機能を取得するためにソースを変更する方法は次のとおりNSPageControllerです。NSPageController IBOutletAppDelegateヘッダーファイルにプロパティを追加します。ファイルにページコントローラーを追加し、MainMenu.xibそのビューをWebViewにワイヤリングし、AppDelegateをデリゲートにして、AppDelegateで作成したプロパティへの参照アウトレットを指定します。また、AppDelegateをWebViewのものにしますframeLoadDelegate。内部basicWebAppDelegate.mにプライベートプロパティを追加します。

@interface basicWebAppDelegate ()
@property (assign) id currentItem;
@end

次に、次の内部実装を追加します。

#pragma mark - WebFrameLoadDelegate

- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame {
  if (frame == [sender mainFrame]) {
    id object = [sender.backForwardList currentItem];
    BOOL isCurrentItem = self.currentItem && (object == self.currentItem) ? YES : NO;
    if (!isCurrentItem) {
      [self.pageController navigateForwardToObject:[sender.backForwardList currentItem]];
    }
  }
}


#pragma mark - NSPageControllerDelegate

- (void)pageControllerWillStartLiveTransition:(NSPageController *)pageController {
  self.currentItem = [self.webView.backForwardList currentItem];
  // Here is where you'll save any state for your pageController.arrangedObjects[pageController.selectedIndex] object
}

- (void)pageController:(NSPageController *)pageController didTransitionToObject:(id)object {
  BOOL isCurrentItem = self.currentItem && (object == self.currentItem) ? YES : NO;
  if (!isCurrentItem) {
    self.currentItem = object;
    [self.webView goToBackForwardItem:object];
  }
}

- (void)pageControllerDidEndLiveTransition:(NSPageController *)pageController {
  self.currentItem = nil;
  [pageController completeTransition];
}

最後に、アクションを変更してgoBack:goForward:それぞれ[self.pageController navigateBack:sender]とを呼び出すだけ[self.pageController navigateForward:sender]にします。

ここではユーザーの状態をわざわざ保存せず、代わりにWebHistoryItemsをオブジェクトとして直接使用したことに注意してください。別の方法で行う必要があるかもしれません。

さらにサポートが必要な場合はお知らせください。

于 2012-12-19T06:49:20.563 に答える
1

差出人: https ://stackoverflow.com/a/13716988/466698

明らかな解決策は、複数のWebビューを使用することかもしれませんが、それらはかなり重い可能性があるため、おそらく使用したくないでしょう。

最善のアイデアは、ページから移動する前に、各ページの画像を保存することです。使用がスワイプバックするときは、保存された画像だけでビューを表示します。スワイプが完了したら、ビューを入れ替えて、Webビュー自体が上になるようにします。

これはSafariがそれを行う方法のようです(画像圧縮が時々見られ、ページをリロードすることが多く、前​​のスクリーンショットから飛び跳ねます)

于 2012-12-15T07:39:10.803 に答える