diff --git a/packages/core/ui/web-view/index.android.ts b/packages/core/ui/web-view/index.android.ts index e9144cc7b..ccf917fff 100644 --- a/packages/core/ui/web-view/index.android.ts +++ b/packages/core/ui/web-view/index.android.ts @@ -1,4 +1,4 @@ -import { WebViewBase, WebViewClient } from './web-view-common'; +import { disableZoomProperty, WebViewBase, WebViewClient } from './web-view-common'; import { Trace } from '../../trace'; import { knownFolders } from '../../file-system'; @@ -107,6 +107,7 @@ export class WebView extends WebViewBase { const client = new WebViewClient(this); nativeView.setWebViewClient(client); (nativeView).client = client; + this._disableZoom(this.disableZoom); } public disposeNativeView() { @@ -119,6 +120,19 @@ export class WebView extends WebViewBase { super.disposeNativeView(); } + private _disableZoom(value: boolean) { + if (this.nativeView && value) { + const settings = this.nativeView.getSettings(); + settings.setBuiltInZoomControls(false); + settings.setSupportZoom(false); + settings.setDisplayZoomControls(false); + } + } + + [disableZoomProperty.setNative](value: boolean) { + this._disableZoom(value); + } + public _loadUrl(src: string) { const nativeView = this.nativeViewProtected; if (!nativeView) { diff --git a/packages/core/ui/web-view/index.ios.ts b/packages/core/ui/web-view/index.ios.ts index 8dd35dedf..efce12e2c 100644 --- a/packages/core/ui/web-view/index.ios.ts +++ b/packages/core/ui/web-view/index.ios.ts @@ -1,5 +1,5 @@ import { WebViewNavigationType } from '.'; -import { WebViewBase } from './web-view-common'; +import { disableZoomProperty, WebViewBase } from './web-view-common'; import { profile } from '../../profiling'; import { Trace } from '../../trace'; export * from './web-view-common'; @@ -96,9 +96,54 @@ class WKNavigationDelegateImpl extends NSObject implements WKNavigationDelegate } } +@NativeClass +@ObjCClass(UIScrollViewDelegate) +class UIScrollViewDelegateImpl extends NSObject implements UIScrollViewDelegate { + public static initWithOwner(owner: WeakRef): UIScrollViewDelegateImpl { + const handler = UIScrollViewDelegateImpl.new(); + handler._owner = owner; + + return handler; + } + + private _owner: WeakRef; + + private _initCurrentValues(scrollView: UIScrollView) { + const owner = this._owner.get(); + if (owner && (owner._minimumZoomScale === undefined || owner._maximumZoomScale === undefined || owner._zoomScale === undefined)) { + owner._minimumZoomScale = scrollView.minimumZoomScale; + owner._maximumZoomScale = scrollView.maximumZoomScale; + owner._zoomScale = scrollView.zoomScale; + } + } + + private _handleDisableZoom(scrollView: UIScrollView) { + const owner = this._owner.get(); + if (owner.disableZoom) { + this._initCurrentValues(scrollView); + scrollView.maximumZoomScale = 1.0; + scrollView.minimumZoomScale = 1.0; + scrollView.zoomScale = 1.0; + } + } + + scrollViewWillBeginZoomingWithView(scrollView: UIScrollView, view: UIView) { + this._handleDisableZoom(scrollView); + } + + scrollViewDidZoom(scrollView) { + this._handleDisableZoom(scrollView); + } +} + export class WebView extends WebViewBase { nativeViewProtected: WKWebView; private _delegate: any; + private _scrollDelegate: any; + + _maximumZoomScale; + _minimumZoomScale; + _zoomScale; createNativeView() { const jScript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'initial-scale=1.0'); document.getElementsByTagName('head')[0].appendChild(meta);"; @@ -118,7 +163,9 @@ export class WebView extends WebViewBase { initNativeView() { super.initNativeView(); this._delegate = WKNavigationDelegateImpl.initWithOwner(new WeakRef(this)); + this._scrollDelegate = UIScrollViewDelegateImpl.initWithOwner(new WeakRef(this)); this.ios.navigationDelegate = this._delegate; + this.ios.scrollView.delegate = this._scrollDelegate; } @profile @@ -171,4 +218,17 @@ export class WebView extends WebViewBase { public reload() { this.ios.reload(); } + + [disableZoomProperty.setNative](value: boolean) { + if (!value && typeof this._minimumZoomScale === 'number' && typeof this._maximumZoomScale === 'number' && typeof this._zoomScale === 'number') { + if (this.ios.scrollView) { + this.ios.scrollView.minimumZoomScale = this._minimumZoomScale; + this.ios.scrollView.maximumZoomScale = this._maximumZoomScale; + this.ios.scrollView.zoomScale = this._zoomScale; + this._minimumZoomScale = undefined; + this._maximumZoomScale = undefined; + this._zoomScale = undefined; + } + } + } } diff --git a/packages/core/ui/web-view/web-view-common.ts b/packages/core/ui/web-view/web-view-common.ts index 17b213b7b..9c95a6045 100644 --- a/packages/core/ui/web-view/web-view-common.ts +++ b/packages/core/ui/web-view/web-view-common.ts @@ -3,11 +3,14 @@ import { ContainerView, CSSType } from '../core/view'; import { Property } from '../core/properties'; import { EventData } from '../../data/observable'; import { knownFolders } from '../../file-system'; +import { booleanConverter } from '../core/view-base'; export * from './web-view-interfaces'; export const srcProperty = new Property({ name: 'src' }); +export const disableZoomProperty = new Property({ name: 'disableZoom', defaultValue: false, valueConverter: booleanConverter }); + @CSSType('WebView') export abstract class WebViewBase extends ContainerView { public static loadStartedEvent = 'loadStarted'; @@ -15,6 +18,8 @@ export abstract class WebViewBase extends ContainerView { public src: string; + public disableZoom: boolean; + public _onLoadFinished(url: string, error?: string) { const args = { eventName: WebViewBase.loadFinishedEvent, @@ -102,3 +107,4 @@ export interface WebViewBase { } srcProperty.register(WebViewBase); +disableZoomProperty.register(WebViewBase);