iOS 10 中 WKWebView 的链接预览 API
多点触控手势一直是 iPhone 体验不可或缺的一部分,但双指缩放和双击只是故事的开端。去年,iPhone 6s 凭借 3D Touch 为多点触控体验引入了全新的维度。支持 3D Touch 的显示屏能够感知用户触摸屏幕时施加的压力大小。利用这项技术,iOS 有了一种全新的 Peek and Pop(预览与弹出)体验,其中一项功能就是让用户在 Safari 中预览内容。我很高兴地宣布一些更新,这些更新也让 WKWebView
开发者能够利用这项功能。
Peek and Pop(预览与弹出)
WebKit 支持 Peek and Pop 作为预览链接的便捷方式。基于 iOS 10 SDK 构建的应用程序将默认启用 Peek and Pop 链接预览功能,但这并非新功能;自 iOS 9 起,WKWebView
客户端就可以通过设置 WKWebView
的 allowsLinkPreview
属性,在支持 3D Touch 的设备上选择启用基于 Peek 的链接预览。当 allowsLinkPreview
属性设置为 true
时,用户可以轻按链接进行 Peek 操作,这会在应用程序上方的新视图中加载链接,并模糊应用程序背景。

如果用户用力按压链接,它就会在 Safari 中弹出(Pop)打开。
并非所有应用程序都相同
这种行为对于邮件(Mail)等应用程序非常适用。邮件使用 WebKit 显示富文本 HTML 内容,但它本身并非网络浏览器,因此链接导航总是会交给 Safari 处理。然而,许多 WebKit 应用程序会处理链接导航,其行为更像网络浏览器。在 iOS 10 中,我们让 Peek and Pop 在这类应用程序中表现得更好。
以 WKPedia 为例。Anders 和我制作了 WKPedia,一个维基百科浏览器应用程序,作为 iOS 8 中 WKWebView
的演示应用。WKPedia 拥有一个 WKNavigationDelegate
,它强制执行导航策略,以便当用户点击指向其他维基百科页面的链接时,WKPedia 会在应用程序内部处理链接导航,但当用户点击托管在任何其他域上的链接时,WKPedia 会将导航交给 Safari 处理。
我已经将 allowsLinkPreview
设置为 true
以启用 Peek and Pop,但默认行为对于此应用并不理想。现在,如果用户轻触链接,WKPedia 会根据加载策略决定是在应用内导航到链接还是将其交给 Safari。但如果她 Peek 并 Pop 该链接,无论加载策略如何,Pop 操作总会在 Safari 中导航到该链接。
在 iOS 10 中自定义 Peek and Pop
如果您有一个像 WKPedia 这样的应用程序,并且希望提供更好的体验,您可以开始使用我们在 iOS 10 中添加的新 API!当用户在 WKWebView
中使用 3D Touch Peek 和 Pop 链接时,这个新 API 会显示一个自定义的视图控制器。它包含 WKUIDelegate
协议中的三个新的委托方法。
optional func webView(_ webView: WKWebView, shouldPreviewElement elementInfo: WKPreviewElementInfo) -> Bool
optional func webView(_ webView: WKWebView, previewingViewControllerForElement elementInfo: WKPreviewElementInfo, defaultActions previewActions: [WKPreviewActionItem]) -> UIViewController?
optional func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController)
第一个方法 webView(_:shouldPreviewElement:)
会在用户触摸到元素时立即调用。返回 false
将完全禁用该元素的预览功能,并阻止调用其他方法。返回 true
将使您有机会在用户施加足够的力以触发 Peek 时提供一个自定义视图控制器。
如果用户确实进入了 Peek 状态,webView(_:previewingViewControllerForElement:defaultActions:)
就是您提供自定义视图控制器的机会。返回任何非 nil 的视图控制器将导致该视图控制器被显示为 Peek 预览。defaultActions
参数是 WebKit 默认将用作此元素的 previewActionItems
的操作数组。如果您希望使用这些操作中的任何一个,只需从您的视图控制器对 previewActionItems
的实现中返回它们即可。这是 WKPedia 对此委托方法的实现
func webView(_ webView: WKWebView, previewingViewControllerForElement elementInfo: WKPreviewElementInfo, defaultActions previewActions: [WKPreviewActionItem]) -> UIViewController? {
// If this URL is not allowed by our navigation policy, then it must not be a link
// to a page on Wikipedia, so returning nil will let WebKit display its default
// preview which will pop to Safari.
if !navigationAllowedForURL(elementInfo.linkURL) {
return nil;
}
let previewViewController = ArticlePreviewController()
previewViewController.view.frame = self.view.frame
previewViewController.view.backgroundColor = UIColor.white()
var actions = [WKPreviewActionItem]()
for previewAction in previewActions {
if previewAction.identifier == WKPreviewActionItemIdentifierShare {
actions.append(previewAction)
}
}
previewViewController.defaultPreviewActionItems = actions
previewViewController.load(request: URLRequest(url:elementInfo.linkURL))
return previewViewController
}
最后,如果用户施加足够的力来 Pop(弹出)视图控制器,webView(_:commitPreviewingViewController:)
将被调用。此时,您可以选择在您的应用程序内部显示弹出的视图控制器。
这个 API 让开发者可以控制 Peek and Pop,从而为用户提供更好的体验。我期待在更多应用程序中看到它的应用!
欲了解更多信息,请通过 @dethbakin 联系我,或通过 @jonathandavis 联系 Apple 的 Web 技术布道师 Jonathan Davis。