Reputation: 9983
I know this looks like a simple question one can simply say:
webview.scrollView.scrollEnabled = NO;
webview.scrollView.panGestureRecognizer.enabled = NO;
webview.scrollView.bounces = NO;
or even
for (UIView* subview in webview.subviews) {
if ([subview respondsToSelector:@selector(setScrollEnabled:)]) {
[(id)subview setScrollEnabled:enabled];
}
if ([subview respondsToSelector:@selector(panGestureRecognizer)]) {
[[(id)subview panGestureRecognizer] setEnabled:enabled];
}
}
but while it does prevent scolling (in the contentOffset
meaning) inside the WKWebview
it doesn't prevent it from receiving pan gesture events involving scrolling.
So articles like those of the Huffington Post, which have javascript included to automatically change articles when the user scrolls left or right still get that behavior.
How can I prevent this ?
Upvotes: 36
Views: 35217
Reputation: 2978
Swift 5
disableScrollView(self.webView)
func disableScrollView(_ view: UIView) {
(view as? UIScrollView)?.isScrollEnabled = false
view.subviews.forEach { disableScrollView($0) }
}
Upvotes: 0
Reputation: 8138
Before Swift 3
You can simply disable scroll on its implicit scrollView
webView.scrollView.scrollEnabled = false
Swift 3
webView.scrollView.isScrollEnabled = false
Upvotes: 58
Reputation: 1316
Here is a C# extension for WKWebView based on alain.s's swift solution (based on apouche's solution) for those of us using Xamarin. I am using this in my app.
Notable differences is that I check if subviews exist before looping and instead of dynamically looking for a "WKContentView" (something I'm not sure is even possible in Xamarin) I simply check if each subview has GestureRecognizers and remove them. This will obviously disable all types of gestures so consider this if you expect any user interaction with the web content.
public static class WKWebViewExtension
{
public static void DisableScroll(this WebKit.WKWebView webView)
{
webView.ScrollView.ScrollEnabled = false;
webView.ScrollView.PanGestureRecognizer.Enabled = false;
webView.ScrollView.Bounces = false;
if (webView.Subviews != null)
{
foreach (var subView in webView.Subviews)
{
if (subView is UIScrollView)
{
UIScrollView subScrollView = (UIScrollView)subView;
subScrollView.ScrollEnabled = false;
subScrollView.Bounces = false;
subScrollView.PanGestureRecognizer.Enabled = false;
}
if (subView.Subviews != null)
{
foreach (var subScrollView in subView.Subviews)
{
if (subScrollView.GestureRecognizers != null)
{
foreach (var gesture in subScrollView.GestureRecognizers)
{
subScrollView.RemoveGestureRecognizer(gesture);
}
}
}
}
}
}
}
}
Upvotes: 1
Reputation: 151
I found that I had to make my view controller a UIScrollViewDelegate
then add this function to prevent scrolling.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
scrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
}
Upvotes: 1
Reputation: 151
Here is a Swift 3 version:
extension WKWebView {
func setScrollEnabled(enabled: Bool) {
self.scrollView.isScrollEnabled = enabled
self.scrollView.panGestureRecognizer.isEnabled = enabled
self.scrollView.bounces = enabled
for subview in self.subviews {
if let subview = subview as? UIScrollView {
subview.isScrollEnabled = enabled
subview.bounces = enabled
subview.panGestureRecognizer.isEnabled = enabled
}
for subScrollView in subview.subviews {
if type(of: subScrollView) == NSClassFromString("WKContentView")! {
for gesture in subScrollView.gestureRecognizers! {
subScrollView.removeGestureRecognizer(gesture)
}
}
}
}
}
}
Upvotes: 1
Reputation: 744
Credit and many thanks to apouche for the Obj-C code. In case anybody else has the same problem, here is the working solution adapted for Swift 2
extension WKWebView {
func setScrollEnabled(enabled: Bool) {
self.scrollView.scrollEnabled = enabled
self.scrollView.panGestureRecognizer.enabled = enabled
self.scrollView.bounces = enabled
for subview in self.subviews {
if let subview = subview as? UIScrollView {
subview.scrollEnabled = enabled
subview.bounces = enabled
subview.panGestureRecognizer.enabled = enabled
}
for subScrollView in subview.subviews {
if subScrollView.dynamicType == NSClassFromString("WKContentView")! {
for gesture in subScrollView.gestureRecognizers! {
subScrollView.removeGestureRecognizer(gesture)
}
}
}
}
}
}
Upvotes: 5
Reputation: 16
Here's a swift version if anyone's still having trouble with this issue
let subviews = self.theWebView.scrollView.subviews
for subview in subviews{
if(subview.isKindOfClass(NSClassFromString("WKContentView"))){
if let recognizers = subview.gestureRecognizers {
for recognizer in recognizers! {
if recognizer.isKindOfClass(NSClassFromString("UIWebTouchEventsGestureRecognizer")){
subview.removeGestureRecognizer(recognizer as! UIGestureRecognizer)
}
}
}
}
}
Upvotes: 0
Reputation: 9983
Took me a while but I figured out a way of doing this.
I had to remove a private gesture recognizer within a private subview of the WKWebView
.
I had a category on WKWebView
to do so:
@implementation WKWebView (Scrolling)
- (void)setScrollEnabled:(BOOL)enabled {
self.scrollView.scrollEnabled = enabled;
self.scrollView.panGestureRecognizer.enabled = enabled;
self.scrollView.bounces = enabled;
// There is one subview as of iOS 8.1 of class WKScrollView
for (UIView* subview in self.subviews) {
if ([subview respondsToSelector:@selector(setScrollEnabled:)]) {
[(id)subview setScrollEnabled:enabled];
}
if ([subview respondsToSelector:@selector(setBounces:)]) {
[(id)subview setBounces:enabled];
}
if ([subview respondsToSelector:@selector(panGestureRecognizer)]) {
[[(id)subview panGestureRecognizer] setEnabled:enabled];
}
// here comes the tricky part, desabling
for (UIView* subScrollView in subview.subviews) {
if ([subScrollView isKindOfClass:NSClassFromString(@"WKContentView")]) {
for (id gesture in [subScrollView gestureRecognizers]) {
if ([gesture isKindOfClass:NSClassFromString(@"UIWebTouchEventsGestureRecognizer")])
[subScrollView removeGestureRecognizer:gesture];
}
}
}
}
}
@end
Hope this helps anyone some day.
Upvotes: 6
Reputation: 502
Try to disable scrollView zoom in this way:
CGFloat zoomScale = webview.scrollView.zoomScale;
webview.scrollView.maximumZoomScale = zoomScale;
webview.scrollView.minimumZoomScale = zoomScale;
Upvotes: -1