UIWebView が垂直方向に「バウンス」するのを止めますか?
-
20-08-2019 - |
質問
UIWebView の垂直方向のバウンスを停止する方法を知っている人はいますか?つまり、ユーザーが iPhone の画面に触れ、指を下にドラッグすると、Web ビューで、私がロードした Web ページの上に空白のスポットが表示されたときですか?
次の考えられる解決策を検討しましたが、どれもうまくいきませんでした。
解決
for (id subview in webView.subviews)
if ([[subview class] isSubclassOfClass: [UIScrollView class]])
((UIScrollView *)subview).bounces = NO;
...うまく機能しているようです。
App Storeでも受け付けられる予定です。
アップデート:iOS 5.x 以降では、もっと簡単な方法があります - UIWebView
もっている scrollView
プロパティを使用すると、コードは次のようになります。
webView.scrollView.bounces = NO;
同じことが当てはまります WKWebView
.
他のヒント
私は、Web アプリを iPhone に本格的にインストール可能なアプリケーションとして簡単に作成できるようにするプロジェクトを検討していました。 クイックコネクト, 、画面をまったくスクロール可能にしたくない場合に機能する解決策を見つけましたが、私の場合はそうではありませんでした。
上記のプロジェクト/ブログ投稿では、バウンスをオフにするために追加できる JavaScript 関数について言及していますが、これは本質的に次のとおりです。
document.ontouchmove = function(event){
event.preventDefault();
}
実装方法について詳しく知りたい場合は、QuickConnect をダウンロードしてチェックしてください。しかし、基本的に行うことは、ページの読み込み時にその JavaScript を呼び出すことだけです...ドキュメントの先頭にそれを挿入してみましたが、うまく機能するようです。
さて、これを達成するために私がやったことは次のとおりです。
UIView *firstView = [webView.subviews firstObject];
if ([firstView isKindOfClass:[UIScrollView class]]) {
UIScrollView *scroll = (UIScrollView*)firstView;
[scroll setScrollEnabled:NO]; //to stop scrolling completely
[scroll setBounces:NO]; //to stop bouncing
}
私にとってはうまくいきます...また、この質問に対するチェックされた答えは、iPhoneアプリで使用するとAppleが拒否するものです。
iOS 5 SDK では、サブビューを反復処理するのではなく、Web ビューに関連付けられたスクロール ビューに直接アクセスできます。
したがって、スクロールビューで「バウンス」を無効にするには、次のように使用できます。
myWebView.scrollView.bounces = NO;
を参照してください。 UIWebView クラスのリファレンス.
(ただし、5.0 より前のバージョンの SDK をサポートする必要がある場合は、次の手順に従ってください。 ミレク・ルーシンのアドバイス.)
スイフト3
webView.scrollView.bounces = false
警告。setAllowsRubberBanding を使用しました。私のアプリでは、非パブリック API 関数は許可されていないとして、Apple がそれを拒否しました (引用:3.3.1)
Swift でバウンスを無効にする
webViewObj.scrollView.bounces = false
ブラッドの方法は私にとってはうまくいきました。使用する場合は、もう少し安全性を高めた方がよいでしょう。
id scrollView = [yourWebView.subviews objectAtIndex:0]; if( [scrollView respondsToSelector:@selector(setAllowsRubberBanding:)] ) { [scrollView performSelector:@selector(setAllowsRubberBanding:) withObject:NO]; }
Apple が何かを変更すると、バウンスは戻りますが、少なくともアプリはクラッシュしません。
iOS5 では、ユーザーが Web ビューのコンテンツをズームできるようにする場合のみ (例:ダブルタップ) バウンス設定が十分ではありません。alwaysBouncehorizontal プロパティと alwaysBounceVertical プロパティも NO に設定する必要があります。そうしないと、ズームアウト (もう一度ダブルタップ...) してデフォルトにすると、再びバウンスします。
UIWebView のサブビューのコレクションを調べて、その背景を Web ページの背景と同じ色である [UIColor blackColor] に設定しました。ビューは引き続きバウンスしますが、醜い濃い灰色の背景は表示されません。
UIWebView には UIScrollView があるように見えます。これには文書化された API を使用できますが、バウンスは個別ではなく両方向に設定されます。これは API ドキュメントに記載されています。UIScrollView には bounce プロパティがあるため、次のようなものが機能します (複数のスクロールビューがあるかどうかはわかりません)。
NSArray *subviews = myWebView.subviews;
NSObject *obj = nil;
int i = 0;
for (; i < subviews.count ; i++)
{
obj = [subviews objectAtIndex:i];
if([[obj class] isSubclassOfClass:[UIScrollView class]] == YES)
{
((UIScrollView*)obj).bounces = NO;
}
}
UIWebView がスクロール ビューではないことを知ってイライラしたので、Web ビューのスクロール ビューを取得するためのカスタム サブクラスを作成しました。この suclass にはスクロール ビューが含まれているため、Web ビューの動作をカスタマイズできます。このクラスのオチは次のとおりです。
@class CustomWebView : UIWebview
...
- (id) initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
// WebViews are subclass of NSObject and not UIScrollView and therefore don't allow customization.
// However, a UIWebView is a UIScrollViewDelegate, so it must CONTAIN a ScrollView somewhere.
// To use a web view like a scroll view, let's traverse the view hierarchy to find the scroll view inside the web view.
for (UIView* v in self.subviews){
if ([v isKindOfClass:[UIScrollView class]]){
_scrollView = (UIScrollView*)v;
break;
}
}
return self;
}
次に、カスタム Web ビューを作成するときに、次のようにバウンスを無効にできます。
customWebView.scrollView.bounces = NO; //(or customWebView.scrollView.alwaysBounceVertically = NO)
これは、スクロール動作をカスタマイズできる Web ビューを作成するための優れた汎用方法です。注意すべき点がいくつかあります。
- 他のビューと同様に、 -(id)initWithCoder もオーバーライドする必要があります。Interface Builder で使用する場合
- 最初に Web ビューを作成するとき、そのコンテンツ サイズは常にビューのフレームのサイズと同じになります。Web をスクロールした後のコンテンツ サイズは、ビュー内の実際の Web コンテンツのサイズを表します。これを回避するために、-setContentOffset:CGPointMake(0,1)animated:YES を呼び出して、Web ビューの適切なコンテンツ サイズを設定する目立たない変更を強制するというハッキングなことを行いました。
答えを探していてこれに遭遇しました、そして最終的には、いじくり回して自分自身の答えを見つけることができました。やった
[[webview scrollView] setBounces:NO];
そしてそれはうまくいきました。
これは私にとってはうまくいきましたが、美しくもうまくいきました(私はwebViewでphonegapを使用しています)
[[webView.webView scrollView] setScrollEnabled:NO];
または
[[webView scrollView] setScrollEnabled:NO];
防ぐために少し異なるアプローチを試してみました UIWebView オブジェクトのスクロールやバウンスが防止されます。他のジェスチャをオーバーライドするジェスチャ認識機能を追加します。
そうみたいです、 UIWebView または、そのスクローラー サブビューは、独自のパン ジェスチャ認識機能を使用してユーザーのスクロールを検出します。しかし、Apple のドキュメントによると、あるジェスチャ認識エンジンを別のジェスチャ認識エンジンでオーバーライドする正当な方法があるようです。 UIGestureRecognizerDelegate プロトコルにはメソッドがある GestureRecognizer:GestureRecognizer と同時に認識する必要があります: - 衝突するジェスチャ認識機能の動作を制御できるようになります。
そこで、私がやったことは、
ビューコントローラーの viewDidLoad メソッド内:
// Install a pan gesture recognizer // We ignore all the touches except the first and try to prevent other pan gestures
// by registering this object as the recognizer's delegate
UIPanGestureRecognizer *recognizer;
recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
recognizer.delegate = self;
recognizer.maximumNumberOfTouches = 1;
[self.view addGestureRecognizer:recognizer];
self.panGestureFixer = recognizer;
[recognizer release];
次に、ジェスチャ オーバーライド メソッド:
// Control gestures precedence
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// Prevent all panning gestures (which do nothing but scroll webViews, something we want to disable in
// the most painless way)
if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
// Just disable every other pan gesture recognizer right away
otherGestureRecognizer.enabled = FALSE;
}
return NO;
}
もちろん、このデリゲート メソッドは実際のアプリケーションではさらに複雑になる可能性があります。分析して他の認識エンジンを選択的に無効にすることもできます。 otherGestureRecognizer.view そしてそれがどのような見解であるかに基づいて決定を下します。
そして最後に、完全を期すために、パン ハンドラーとして登録したメソッドを示します。
- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer
{
// do nothing as of yet
}
Web ビューのスクロールとバウンスをキャンセルしたいだけの場合は空にすることもできます。または、本当に必要な種類のパン モーションやアニメーションを実装するための独自のコードを含めることもできます...
これまでのところ、私はこれらすべてを試しているところですが、多かれ少なかれ希望どおりに機能しているようです。ただし、まだアプリを iStore に提出しようとしたことはありません。しかし、これまで文書化されていないものは何も使用していないと思います...誰かがそれを見つけたら、私に知らせてください。
ここでは、2 つの新しい潜在的なソリューションを紹介します。どうやら、jqtouch または pastrykit を使用してスクロールを無効にできるようです。ただし、これらを機能させることができません。あなたはもっと有能かもしれません。
このリンクはとても役に立ちました。簡単です。デモがあります。
(Xcode 5 iOS 7 SDK の例) 以下は、scrollview setBounces 関数を使用したユニバーサル アプリの例です。これはオープンソース プロジェクト/サンプルであり、次の場所にあります。 SimpleWebView へのリンク (プロジェクト ZIP とソース コードの例)
のサブビューの 1 つ UIWebView
であるべきです UIScrollView
. 。設定します scrollEnabled
財産を NO
Web ビューではスクロールが完全に無効になります。
注記:これは技術的にはプライベート API を使用しているため、将来の OS リリースではアプリが拒否されたり、クラッシュしたりする可能性があります。使用 @try
そして respondsToSelector
調べてください bounces
の財産 UIScrollView
. 。Apple のドキュメントを引用します。
プロパティの値が
YES
(デフォルト)、スクロール ビューはコンテンツの境界に遭遇すると跳ね返ります。バウンスは、スクロールがコンテンツの端に到達したことを視覚的に示します。値がNO
, 、スクロールはバウンドすることなく、コンテンツの境界ですぐに停止します。
正しいものを使用していることを確認してください UIScrollView
. 。階層がどのようなものであるかわかりません UIWebView
, ただし、スクロール ビューは子ではなく親になる可能性があります。 UIWebView
.
無効にするには UIWebView
スクロールするには、次のコード行を使用できます。
[ObjWebview setUserInteractionEnabled:FALSE];
この例では、 ObjWebview
タイプです UIWebView
.
webView.scrollView.scrollEnabled=NO;webView.scrollView.bounces=NO;