Using Swift 3, Xcode 8.2.1
I am displaying web content in a WKWebView. Horizontal scrolling is turned off automatically because the content width equals the screen width. Vertical scrolling is enabled to scroll through the content. I have implemented a right and left swipe gesture recognizer. When the user swipes either right or left the App will take them to another web page. (The new web page is driven by the App logic and is not based on the "browsing history".)
The code works, however the swipes are sluggish. Sometimes it works great and I can quickly more from one web page to another. Other times, the horizontal swiping does nothing and you have to repeat the swipes many times before the gesture is triggered. I feel that the vertical scrolling in the WKWebView may be intefering with the horizontal swipe recognizers.
Is there a way to eliminate this sluggishness? Alternatively, is there a way to code this so that all mostly horizontal gestures are interpreted as swipes and all mostly vertical gestures are interpreted as scrolls without the App getting confused about what the user wants to do?
Below is the relevant code. (Please note that I have global variables set and that I am passing in the value of currentContent via a segue.)
class viewController: UIViewController, WKUIDelegate, WKNavigationDelegate, UIScrollViewDelegate {
var url: String?
var currentContent: Int = 0
var webView: WKWebView!
override func loadView() {
// Create a Web View
let webConfiguration = WKWebViewConfiguration()
let webFrame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight )
webView = WKWebView(frame: webFrame, configuration: webConfiguration)
// Add right and left swipe monitor
let rightSwipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(contentSwipeRightDetected))
rightSwipeGesture.direction = [.right]
webView.addGestureRecognizer(rightSwipeGesture)
let leftSwipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(contentSwipeLeftDetected))
leftSwipeGesture.direction = [.left]
webView.addGestureRecognizer(leftSwipeGesture)
// Necessary to render web page and have links show up in Safari
webView.uiDelegate = self
webView.navigationDelegate = self
webView.scrollView.bounces = false // Prevents bouncing when reaching top or bottom
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
// Content was previously downloaded.
webView.loadHTMLString(htmlString, baseURL: nil)
webView.scrollView.delegate = self
}
// On Swipe Left, move to previous content unless user is at the first content.
func contentSwipeLeftDetected() {
if currentContent != 0 {
currentContent -= 1
webView.loadHTMLString(htmlString, baseURL: nil)
}
}
// On Swipe Right, move to next content unless user is at the last content.
func contentSwipeRightDetected() {
if currentContent != maxContents {
currentContent += 1
webView.loadHTMLString(htmlString, baseURL: nil)
}
}
// Have WKWebView links render in Safari and disabled in App
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
if let url = navigationAction.request.url, true {
decisionHandler(WKNavigationActionPolicy.cancel)
UIApplication.shared.open(url)
} else {
decisionHandler(WKNavigationActionPolicy.allow)
}
} else {
decisionHandler(WKNavigationActionPolicy.allow)
}
}
...
}