如何实现NSPageController通过的WebView历史浏览 [英] How do you implement NSPageController to navigate through a webView's history

查看:803
本文介绍了如何实现NSPageController通过的WebView历史浏览的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有基于网页视图的应用程序,但我希望用户能够与刷卡上的触控板和魔术鼠标导航吧。因此,我要实现NSPageController。

我已经看过的文件和应用程序PictureSwiper但是这些是不是真的意味着网页视图。所以,我想知道我可以在网页视图使用NSPageController。我定义为网​​页视图web视图和两个动作,GoBack的:和goForward:分别加载previous和下一页。

不过,我不知道我是怎么NSPageController用一个简单的web视图工作。这里有一个是一个办法做到这一点,但我看到没有办法。如果有人能解释一下什么,我想这样做,那将是巨大的。或者,如果你感觉特别大方,你可以下载我的免费浏览器源的例子。 https://sites.google.com/site/infiniteopensyntax/basic-web-browser

这是源显示自己的应用程序是如何pretty多成立。如果您想实现NSPageController上的应用程序,并给我的来源,我真的AP preciate它。这不是很多,但如果你这样做,我会加入刷卡例子无限开放的语法和把你的名字就可以了。您可以选择该许可证。

这是可可,可可没有触摸

修改

好吧,现在我只是需要确保应用程序仍然工作雪豹。按说,我可以通过断开插座进行测试。它工作正常,减去后退和前进按钮。要做到这一点,我相信我检查类NSPageController。如果它不存在,那么我就跳过使用的PageController。

   - (IBAction为)GoBack的:(ID)发送{
    如果(NSClassFromString(@NSPageController)!=无)
    {
        [self.pageController navigateBack:寄件人];
    }
    {         //不10.8
        [web视图GoBack的];
    }
}


解决方案

您联系不起作用页面上的下载链接,所以我会保持我的答案比较一般。

您不必保留多个网页视图,或者如果你使用手动生成快照 NSPageController ;它需要照顾你们。在你的情况,你要使用 NSPageController 在<一个href=\"http://developer.apple.com/library/Mac/documentation/AppKit/Reference/NSPageController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40012265-CH1-SW19\"相对=nofollow>历史模式。要做到这一点,你的接线的WebView pageController.view 。您将需要实现三个 NSPageControllerDelegate 方法:

   - (无效)pageControllerWillStartLiveTransition:(NSPageController *)的PageController;
- (无效)的PageController:(NSPageController *)的PageController didTransitionToObject:(id)的对象;
- (无效)pageControllerDidEndLiveTransition:(NSPageController *)的PageController;

每一次的WebView进入一个新的页面(不通过前进/后退操作),调用<一个href=\"http://developer.apple.com/library/Mac/documentation/AppKit/Reference/NSPageController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40012265-CH1-SW14\"相对=nofollow> navigateForwardToObject:(ID)对象 上的的PageController 。我会做对象,对于导航的页面存储用户状态的自定义对象(滚动位置,高亮显示的文本,表格内容等),以及页面的<一个href=\"https://developer.apple.com/library/mac/documentation/Cocoa/Reference/WebKit/Classes/WebHistoryItem_Class/Reference/Reference.html#//apple_ref/doc/c_ref/WebHistoryItem\"相对=nofollow> WebHistoryItem 。用户状态可以初步不确定,但应该在被置pageControllerWillStartLiveTransition:。这里有一个例子:

   - (无效)pageControllerWillStartLiveTransition:(NSPageController *)的PageController
{
  //记住用户状态
  MyCustomObject *对象= [self.pageController.arrangedObjects objectAtIndex:self.pageController.selectedIndex];
  object.userState = someUserState;
}

当该方法返回时,的PageController 将隐藏其视图(web视图),而是它认为的previous状态显示快照。

一旦刷卡动画完成,的PageController:didTransitionToObject:将被调用。凉。你应该在这个方法做的就是抓住 WebHistoryItem 对象并具有的WebView使用回到那个项目在<一个href=\"https://developer.apple.com/library/mac/documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/Reference/Reference.html#//apple_ref/doc/uid/20001903-BABFADDF\"相对=nofollow> goToBackForwardItem: 方法。你也应该守住你存储在对象用户状态(比如,在一个实例变量),因为你需要一次的WebView恢复加载完毕。

最后,在 pageControllerDidEndLiveTransition:你做什么,你重新显示的WebView之前想完成。我希望这将是没什么,因为是不可恢复的用户状态,直到WebView中完成加载,所以你需要在它的实施将 [的PageController completeTransition]

最后一个细节是后退/前进按钮。你应该实现它们,你会正常,但也有叫他们 navigateBack: navigateForward:上的PageController。

这pretty盖得多了。我还没有真正尝试这个具体的例子,所以让我知道如果你遇到任何问题。

修改

下面就是我想修改源得到基本 NSPageController 功能。在你的AppDelegate头文件中添加 NSPageController IBOutlet中属性。在你的 MainMenu.xib 文件中添加页面控制器,电线其观点,您的WebView,让你的AppDelegate其委托,并给它一个参照出口到我们刚创建的​​属性的AppDelegate中。此外,请你的AppDelegate您的WebView frameLoadDelegate 。在 basicWebAppDelegate.m 添加一个私有财产:

  @interface basicWebAppDelegate()
@property(分配)的ID CURRENTITEM;
@结束

然后添加以下内实现:

 的#pragma马克 -  WebFrameLoadDelegate - (无效)web视图:(* web视图)发件人didCommitLoadForFrame:(WebFrame *)帧{
  如果(帧== [发送主机]){
    ID对象= [sender.backForwardList CURRENTITEM]
    BOOL isCurrentItem = self.currentItem&放大器;&安培; (对象== self.currentItem)?是:否;
    如果(!isCurrentItem){
      [self.pageController navigateForwardToObject:[sender.backForwardList CURRENTITEM]];
    }
  }
}
的#pragma马克 - NSPageControllerDelegate - (无效)pageControllerWillStartLiveTransition:(NSPageController *)的PageController {
  self.currentItem = [self.webView.backForwardList CURRENTITEM]
  //在这里你会保存任何状态为您pageController.arrangedObjects [pageController.selectedIndex]对象
} - (无效)的PageController:(NSPageController *)的PageController didTransitionToObject:(ID){对象
  BOOL isCurrentItem = self.currentItem&放大器;&安培; (对象== self.currentItem)?是:否;
  如果(!isCurrentItem){
    self.currentItem =对象;
    [self.webView goToBackForwardItem:对象]。
  }
} - (无效)pageControllerDidEndLiveTransition:(NSPageController *)的PageController {
  self.currentItem =零;
  [的PageController completeTransition]
}

最后,修改你的 GoBack的: goForward:的行动只是调用 [个体经营.pageController navigateBack:发件人] [self.pageController navigateForward:发送方] ,分别为

请注意,我没有理会这里保存,而是任何用户状态下使用 WebHistoryItem 取值直接作为对象。你可能需要做的是不同的。

让我知道如果你需要更多的帮助。

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 use NSPageController in History Mode. To do that, wire your WebView to pageController.view. You will need to implement three NSPageControllerDelegate methods:

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

Every time the WebView goes to a new page (not through a back/forward action), call navigateForwardToObject:(id)object on the pageController. I would make object a custom object that stores user state for a navigated page (scroll positions, highlighted text, form contents, etc.) as well as the page's WebHistoryItem. The user state can be undefined initially, but should get set in pageControllerWillStartLiveTransition:. Here's an example:

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

When that method returns, the pageController will 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 the WebHistoryItem out of object and have the WebView go back to that item using the goToBackForwardItem: method. You should also hold onto the user state you stored in object (say, in an instance variable), because you'll need to restore it once WebView finishes 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: or navigateForward: 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 NSPageController functionality. Add an NSPageController IBOutlet property in your AppDelegate header file. In your MainMenu.xib 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 frameLoadDelegate. Inside basicWebAppDelegate.m add a private property:

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

Then add the following inside implementation:

#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];
}

Finally, change your goBack: and goForward: 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.

这篇关于如何实现NSPageController通过的WebView历史浏览的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆