I have a webView-based app, but I want the user to be able to navigate it with swiping on the trackpad and magic mouse. Therefore, I am going to implement NSPageController.
I have looked at the documentation and the PictureSwiper app, however those aren’t really meant for a webView. So, I would like to know how I can use an NSPageController on a webView. I have a webView defined as webView and two actions, goBack: and goForward: that load the previous and next page respectively.
However, I am unaware of how I get NSPageController to work with a simple webView. There has a to be a way to do it, but I see no way. If someone could please explain what I am suppose to do, that would be great. Or if you are feeling especially generous, you can download my free browser source example. https://sites.google.com/site/infiniteopensyntax/basic-web-browser
That source shows how my own app is pretty much set up. If you would like to implement the NSPageController on that app and send me the source, I would really appreciate it. It’s not much, but if you do that I’ll add the swiping example to Infinite Open Syntax and put your name on it. You can choose the license.
This is Cocoa, not Cocoa Touch
EDIT
Okay, now I just need to make sure the app still works on Snow Leopard. Supposedly, I can test this by disconnecting the outlets. It works fine, minus the back and forward button. To do this, I believe I check for the class NSPageController. If it doesn’t exist, then I just skip using the pageController.
- (IBAction)goBack:(id)sender {
if (NSClassFromString(@"NSPageController") != Nil)
{
[self.pageController navigateBack:sender];
}
{
//Not 10.8
[webView goBack];
}
}
The download link on the page you linked to doesn’t work, so I’ll keep my answer more general.
You don’t need to keep multiple WebViews or manually generate snapshots if you’re using
NSPageController; it takes care of that for you. In your case, you want to useNSPageControllerin History Mode. To do that, wire yourWebViewtopageController.view. You will need to implement threeNSPageControllerDelegatemethods:Every time the WebView goes to a new page (not through a back/forward action), call
navigateForwardToObject:(id)objecton thepageController. I would makeobjecta custom object that stores user state for a navigated page (scroll positions, highlighted text, form contents, etc.) as well as the page’sWebHistoryItem. The user state can be undefined initially, but should get set inpageControllerWillStartLiveTransition:. Here’s an example:When that method returns, the
pageControllerwill hide its view (the WebView) and display snapshots of previous states of its view instead.Once the swiping animation is complete,
pageController:didTransitionToObject:will get called. Cool. What you should do in that method is grab theWebHistoryItemout ofobjectand have the WebView go back to that item using thegoToBackForwardItem:method. You should also hold onto the user state you stored inobject(say, in an instance variable), because you’ll need to restore it onceWebViewfinishes loading.Lastly, in
pageControllerDidEndLiveTransition: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[pageController completeTransition].One last detail is the back/forward buttons. You should implement them as you would normally, but also have them call
navigateBack:ornavigateForward:on the pageController.That pretty much covers it. I haven’t actually tried this specific example, so let me know if you run into any problems.
Edit
Here’s how I’d modify your source to get basic
NSPageControllerfunctionality. Add anNSPageController IBOutletproperty in your AppDelegate header file. In yourMainMenu.xibfile 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’sframeLoadDelegate. InsidebasicWebAppDelegate.madd a private property:Then add the following inside implementation:
Finally, change your
goBack:andgoForward:actions to just call[self.pageController navigateBack:sender]and[self.pageController navigateForward:sender], respectively.Note that I didn’t bother saving any user state here and instead used
WebHistoryItems directly as the objects. You might need to do differently.Let me know if you need more help.