我有一个基于webView的应用程序,但我希望用户能够通过在触控板和魔术鼠标上滑动来导航它。因此,我将实现NSPageController。
我查看过文档和PictureSwiper应用程序,但这些并不适用于webView。所以,我想知道如何在webView上使用NSPageController。我有一个定义为webView
的webView和两个动作,goBack:和goForward:分别加载上一页和下一页。
但是,我不知道如何让NSPageController与简单的webView一起使用。有一种方法可以做到,但我认为没办法。如果有人可以解释我想要做什么,那就太好了。或者,如果您感觉特别慷慨,可以下载我的免费浏览器源示例。 https://sites.google.com/site/infiniteopensyntax/basic-web-browser
该来源显示了我自己的应用程序是如何设置的。如果您想在该应用程序上实现NSPageController并向我发送源代码,我将非常感激。它并不多,但如果您这样做,我会将滑动示例添加到无限开放语法并将您的名字放在上面。您可以选择许可证。
这是Cocoa,而不是Cocoa Touch
修改
好的,现在我只需要确保该应用程序仍适用于Snow Leopard。据说,我可以通过断开插座来测试这一点。它工作正常,减去后退和前进按钮。为此,我相信我检查了NSPageController类。如果它不存在,那么我只是跳过使用pageController。
- (IBAction)goBack:(id)sender {
if (NSClassFromString(@"NSPageController") != Nil)
{
[self.pageController navigateBack:sender];
}
{
//Not 10.8
[webView goBack];
}
}
答案 0 :(得分:9)
您链接到的页面上的下载链接不起作用,因此我会更一般地回答我的问题。
如果您使用NSPageController
,则无需保留多个WebView或手动生成快照;它会照顾你。在您的情况下,您希望在History Mode中使用NSPageController
。为此,请将WebView
与pageController.view
联系起来。您需要实现三种NSPageControllerDelegate
方法:
- (void)pageControllerWillStartLiveTransition:(NSPageController *)pageController;
- (void)pageController:(NSPageController *)pageController didTransitionToObject:(id)object;
- (void)pageControllerDidEndLiveTransition:(NSPageController *)pageController;
每次WebView转到新页面时(而不是通过后退/前进动作),请致电pageController
上的navigateForwardToObject:(id)object
。我会使object
自定义对象存储导航页面的用户状态(滚动位置,突出显示的文本,表单内容等)以及页面的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:
将被调用。凉。您应该在该方法中执行的操作是从WebHistoryItem
中获取object
并让WebView使用goToBackForwardItem:
方法返回该项目。您还应该保留存储在object
中的用户状态(例如,在实例变量中),因为您需要在WebView
完成加载后恢复它。
最后,在pageControllerDidEndLiveTransition:
中,您可以在重新显示WebView之前执行任何操作。我希望这没什么,因为在WebView完成加载之前不会恢复用户状态,因此在实现中你需要的只是[pageController completeTransition]
。
最后一个细节是后退/前进按钮。您应该像平常一样实现它们,但也可以让它们在pageController上调用navigateBack:
或navigateForward:
。
这几乎涵盖了它。我还没有尝试过这个具体的例子,所以如果你遇到任何问题,请告诉我。
以下是我修改源代码以获取基本NSPageController
功能的方法。在AppDelegate头文件中添加NSPageController IBOutlet
属性。在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]
。
请注意,我没有在此处保存任何用户状态,而是直接使用WebHistoryItem
作为对象。您可能需要做不同的事情。
如果您需要更多帮助,请与我联系。
答案 1 :(得分:1)
自: https://stackoverflow.com/a/13716988/466698
一个显而易见的解决方案可能是使用多个Web视图,但由于它们可能非常重,您可能不想这样做。
最好的想法可能是在导航远离它之前保存每个页面的图像。当用户向后滑动时,仅显示已保存图像的视图。滑动完成后,交换视图,以便Web视图本身位于顶部。
这似乎是Safari的做法(你有时可以看到图像压缩,它经常重新加载页面,它会跳过前一个屏幕截图)