Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The download link on the page you linked to doesn't work, so I'll keep my answer more general. </p> <p>You don't need to keep multiple WebViews or manually generate snapshots if you're using <code>NSPageController</code>; it takes care of that for you. In your case, you want to use <code>NSPageController</code> in <a href="http://developer.apple.com/library/Mac/documentation/AppKit/Reference/NSPageController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40012265-CH1-SW19" rel="noreferrer">History Mode</a>. To do that, wire your <code>WebView</code> to <code>pageController.view</code>. You will need to implement three <code>NSPageControllerDelegate</code> methods:</p> <pre><code>- (void)pageControllerWillStartLiveTransition:(NSPageController *)pageController; - (void)pageController:(NSPageController *)pageController didTransitionToObject:(id)object; - (void)pageControllerDidEndLiveTransition:(NSPageController *)pageController; </code></pre> <p>Every time the WebView goes to a new page (not through a back/forward action), call <a href="http://developer.apple.com/library/Mac/documentation/AppKit/Reference/NSPageController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40012265-CH1-SW14" rel="noreferrer"><code>navigateForwardToObject:(id)object</code></a> on the <code>pageController</code>. I would make <code>object</code> a custom object that stores user state for a navigated page (scroll positions, highlighted text, form contents, etc.) as well as the page's <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/WebKit/Classes/WebHistoryItem_Class/Reference/Reference.html#//apple_ref/doc/c_ref/WebHistoryItem" rel="noreferrer"><code>WebHistoryItem</code></a>. The user state can be undefined initially, but should get set in <code>pageControllerWillStartLiveTransition:</code>. Here's an example:</p> <pre><code>- (void)pageControllerWillStartLiveTransition:(NSPageController *)pageController { // Remember user state MyCustomObject *object = [self.pageController.arrangedObjects objectAtIndex:self.pageController.selectedIndex]; object.userState = someUserState; } </code></pre> <p>When that method returns, the <code>pageController</code> will hide its view (the WebView) and display snapshots of previous states of its view instead. </p> <p>Once the swiping animation is complete, <code>pageController:didTransitionToObject:</code> will get called. Cool. What you should do in that method is grab the <code>WebHistoryItem</code> out of <code>object</code> and have the WebView go back to that item using the <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/Reference/Reference.html#//apple_ref/doc/uid/20001903-BABFADDF" rel="noreferrer"><code>goToBackForwardItem:</code></a> method. You should also hold onto the user state you stored in <code>object</code> (say, in an instance variable), because you'll need to restore it once <code>WebView</code> finishes loading.</p> <p>Lastly, in <code>pageControllerDidEndLiveTransition:</code> you do anything you want done before redisplaying the WebView. I expect that would be nothing, since the user state isn't restored until the WebView finishes loading, so all you would need in its implementation would be <code>[pageController completeTransition]</code>. </p> <p>One last detail is the back/forward buttons. You should implement them as you would normally, but also have them call <code>navigateBack:</code> or <code>navigateForward:</code> on the pageController. </p> <p>That pretty much covers it. I haven't actually tried this specific example, so let me know if you run into any problems.</p> <h2>Edit</h2> <p>Here's how I'd modify your source to get basic <code>NSPageController</code> functionality. Add an <code>NSPageController IBOutlet</code> property in your AppDelegate header file. In your <code>MainMenu.xib</code> file add the page controller, wire its view to your WebView, make your AppDelegate its delegate, and give it a referencing outlet to the property we just created in the AppDelegate. Also, make your AppDelegate your WebView's <code>frameLoadDelegate</code>. Inside <code>basicWebAppDelegate.m</code> add a private property:</p> <pre><code>@interface basicWebAppDelegate () @property (assign) id currentItem; @end </code></pre> <p>Then add the following inside implementation:</p> <pre><code>#pragma mark - WebFrameLoadDelegate - (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame { if (frame == [sender mainFrame]) { id object = [sender.backForwardList currentItem]; BOOL isCurrentItem = self.currentItem &amp;&amp; (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 &amp;&amp; (object == self.currentItem) ? YES : NO; if (!isCurrentItem) { self.currentItem = object; [self.webView goToBackForwardItem:object]; } } - (void)pageControllerDidEndLiveTransition:(NSPageController *)pageController { self.currentItem = nil; [pageController completeTransition]; } </code></pre> <p>Finally, change your <code>goBack:</code> and <code>goForward:</code> actions to just call <code>[self.pageController navigateBack:sender]</code> and <code>[self.pageController navigateForward:sender]</code>, respectively.</p> <p>Note that I didn't bother saving any user state here and instead used <code>WebHistoryItem</code>s directly as the objects. You might need to do differently.</p> <p>Let me know if you need more help.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload