UIWebViewが垂直方向に「バウンド」しないようにしますか?


225

UIWebViewが垂直方向にバウンドしないようにする方法を知っている人はいますか?つまり、ユーザーがiphone画面に触れて指を下方向にドラッグすると、ロードしたWebページの上にWebビューに空白のスポットが表示されます。

私は以下の可能な解決策を見ましたが、それらのどれも私にとってうまくいきませんでした:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/996-turn-off-scrolling-bounces-uiwebview.html

http://forums.macrumors.com/showthread.php?t=619534

UIScrollViewが水平方向にバウンドしないようにするにはどうすればよいですか?


1
その機能を無効にすることのユーザビリティへの影響を検討していただければ幸いです。それは理由があります。とは言っても、私はあなたがどうやってそれをするのかにも興味があります。
マイケルハーレン、

アプリに埋め込む方法は、他のいくつかのビュー要素でシームレスに表示されますが、表示されないのはバウンスが発生したときだけです...間違いなく良い点です!
ブラッドパークス

回答:


424
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


できます。サブクラス化は必要ありません。AppleがUIWebView階層を変更しても、クラッシュすることはありません。
leolobato-

2
この修正は私のOS 4.1 Simulatorでのみ機能し、私のOS 3.1.3 iPhoneでは機能しないようです。この修正が特定のOSバージョンでのみ機能するかどうか誰かが知っていますか?
Dan J

@MirukRusin-このアプリが3行のコードに基づいて受け入れられることをどのように保証できますか?:P
モシェ

@Mirek-あなたは私のポイントを逃しました。アプリの他の何もそれが拒否されないことをどうやって知っていますか?
Moshe

6
これでうまくいきました。便宜上、カテゴリを追加して、どこにでもUIWebView電話[webView setBounces:NO]できるようにしました。
ゼケル

46

私は、QuickConnectと呼ばれるiPhoneで本格的なインストール可能なアプリケーションとしてWebアプリを簡単に作成できるプロジェクトを探していて、画面をスクロールできないようにしたい場合に機能する解決策を見つけました。私はしませんでした。

上記のプロジェクト/ブログの投稿では、バウンスをオフにするために追加できるJavaScript関数について言及しています。

    document.ontouchmove = function(event){
        event.preventDefault();
    }

それらがどのように実装されているかについてもっと知りたい場合は、QuickConnectをダウンロードしてチェックアウトするだけです。そしてそれはうまくいくようです。


この答えは、UIWebView内のコンテンツの垂直スクロールを停止する正しい方法です。
Jessedc 2010年

3
完全な答えを出すこともできます。最初に、別のアプリのソースコード全体をダウンロードしたくないので、それを見つけることさえできません。あなたの答えはあなたが答えたときと同じである別のウェブサイトに依存しています。
ジョナサン。

この答えと上記の受け入れられた答えは時々必要となるようです。私の場合、Webビューがまだ読み込まれていない場合、上記のJSが実際にシステムに読み込まれるまでは、弾力性が存在することがわかりました。したがって、答えは、これと上記の受け入れられた答えの両方が必要な場合があります。
Kalle

3
Jessedcが言ったように、これは跳ねるだけでなく、垂直スクロールを停止します。つまり、スクロールが必要なdivなどがある場合、スクロールしません。
memical

18

これを達成するために私がやったすべては次のとおりです。

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が拒否するものです。


3
これが最善かつ最も簡単な方法です。これは受け入れられる答えになるはずです!+1
PostCodeism 2010年

3
それをしないでください-私のアプリは最初の行を使用するために拒否されました。私にとっては多くの時間を無駄にしました。[[webView.subviews lastObject] setScrollEnabled:NO]を使用しました。そしてアップルはそれがプライベートAPIであり、それゆえそれを拒否したと言った。今すぐ再送信しようとしていますが、「userInteractionEnabled:NO」を使用しました。これは、アプリにアクティブなリンクが必要ないためです。
Veeru

UIWebViewはUIViewを継承しています。UIViewにはプロパティサブビューがあります。ここでプライベートとは何ですか?これらすべては、developer.apple.comで見つけることができます
Valerii Pavlov

3
これを使用して、アプリストアに4つのアプリのようなものがあります。あなたのアプリは明らかに別の理由で拒否されました。これはプライベートAPIではありません。
ジグルズワース2009

4
これは本当に良い考えではありません。現在のところ、これがUIScrollView最初のサブビューでUIWebViewある可能性が高いという事実に依存していますが、これはiOSまたは特定の構成に対する将来の(マイナーな)更新でも簡単に変更される可能性があります。実際にを見つけるには、実際にforイテレーションを行う必要がありsubviewsますUIScrollView(実際にはそれほど多くの作業ではありません。少なくともUIScrollView、プログラムを取得し、プログラムをクラッシュさせないことが保証されます...
Jonathan Ellis

17

iOS 5 SDKでは、サブビューを繰り返し処理するのではなく、Webビューに関連付けられたスクロールビューに直接アクセスできます。

したがって、スクロールビューで「バウンス」を無効にするには、次のように使用できます。

myWebView.scrollView.bounces = NO;

UIWebViewクラスリファレンスを参照してください

(ただし、5.0より前のバージョンのSDKをサポートする必要がある場合は、Mirek Rusinのアドバイスに従ってください。)



9

警告。私はアプリでsetAllowsRubberBanding:を使用しましたが、Appleはそれを拒否し、非公開API関数は許可されていないと述べました(引用:3.3.1)



3

ブラッドの方法がうまくいきました。使用する場合は、もう少し安全にすることができます。

id scrollView = [yourWebView.subviews objectAtIndex:0];
if([scrollView respondsToSelector:@selector(setAllowsRubberBanding :)])
{
    [scrollView performSelector:@selector(setAllowsRubberBanding :) withObject:NO];
}

アップルが何かを変更すると、バウンスが戻ってきますが、少なくともアプリはクラッシュしません。


3

iOS5では、ユーザーにWebviewコンテンツをズームさせる(ei:ダブルタップ)ことを計画している場合のみ、バウンス設定は十分ではありません。alwaysBounceHorizo​​ntalプロパティとalwaysBounceVerticalプロパティもNOに設定する必要があります。それ以外の場合は、ズームアウト(別のダブルタップ...)するとデフォルトで再びバウンスします。


2

UIWebViewのサブビューのコレクションをたどって、その背景を[UIColor blackColor]に設定しました。これは、Webページの背景と同じ色です。ビューはまだバウンドしますが、その醜い暗い灰色の背景は表示されません。


1
実際、これはかなり悪いことです。AppleがUIWebViewの内部を変更した場合、このハックが壊れる可能性があるためです。
bpapa

2

UIWebViewにUIScrollViewがあるように見えます。文書化されたAPIを使用できますが、バウンスは双方向ではなく個別に設定されます。これはAPIドキュメントにあります。UIScrollViewにはバウンスプロパティがあるため、次のようなものが機能します(複数のスクロールビューがあるかどうかはわかりません)。

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;
    }
}

2

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:をオーバーライドする必要もあります。インターフェイスビルダーで使用する場合
  • 最初にWebビューを作成するとき、そのコンテンツサイズは常にビューのフレームのサイズと同じです。Webをスクロールすると、コンテンツサイズはビュー内の実際のWebコンテンツのサイズを表します。これを回避するために、私は何かハッキーなことをしました--setContentOffset:CGPointMake(0,1)animated:YESを呼び出して、Webビューの適切なコンテンツサイズを設定する目立たない変更を強制しました。

2

答えを探してこれに出くわしました、そして私はついに私自身をいじることによって自分の答えを見つけました。やった

[[webview scrollView] setBounces:NO];

そしてそれは働いた。


2

これは私にとってもうまくいきました(webViewでPhoneGapを使用しています)

[[webView.webView scrollView] setScrollEnabled:NO];

または

[[webView scrollView] setScrollEnabled:NO];

1

UIWebViewオブジェクトがスクロールおよびバウンスするのを防ぐために、少し異なるアプローチを試しました。他のジェスチャーをオーバーライドするジェスチャー認識機能を追加しました。

これは、と思われるのUIWebViewまたはそのスクロールのサブビューは、ユーザーのスクロールを検出するために、独自のパンジェスチャー認識装置を使用しています。しかし、Appleのドキュメントによると、1つのジェスチャー認識機能を別の認識機能で上書きする正当な方法があります。UIGestureRecognizerDelegateプロトコルにはメソッドgestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: -あり、衝突するジェスチャーの動作を制御できます。

だから、私がしたことは

ビューコントローラーの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を分析し、それがどのビューであるかに基づいて決定を下します。

そして最後に、完全を期すために、panハンドラーとして登録したメソッド:

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer 
{ 
    // do nothing as of yet
}

Webビューのスクロールとバウンスをキャンセルすることだけが目的の場合は空にすることも、実際に必要な種類のパンモーションやアニメーションを実装するための独自のコードを含めることもできます...

これまでのところ、私はこのすべてのものを実験しているだけであり、それは多かれ少なかれ私が望むように機能しているようです。ただし、まだiStoreにアプリを送信することはしていません。しかし、私はこれまでに文書化されていないものは何も使用していないと思います...もし誰かがそれを見つけたら、私に知らせてください。





0

サブビューの一つがUIWebViewなければなりませんUIScrollViewscrollEnabledプロパティをに設定するNOと、Webビューでスクロールが完全に無効になります。

注:これは技術的にプライベートAPIを使用しているため、将来のOSリリースでアプリが拒否されるかクラッシュする可能性があります。使用@tryしてrespondsToSelector


私はこれを試してみましたが、試すとエラーになります...奇妙なことに、scrollView.bouncesにアクセスして設定できます(効果なし)が、scrollEnabledを設定してみるとエラーになります...
Brad Parks

サブビューはUIScrollViewではなくUIScrollerと呼ばれていると思います。UIScrollerは、ドキュメント化されておらず、サポートされていないクラスであり、UIScrollViewと多くの共通点がありますが、すべてが同じように機能し、将来のOSバージョンで変更されないことに依存することはできません。
マルコ、

iOS 3.2を実行しているiPad(iPhoneではない)アプリでこれを行い、UIWebViewからUIScrollViewを取得することができました。私はこのビューをカスタマイズして、跳ねる動作だけでなくそれ以上の変更を加えたので、iPadでこれが機能していることを証明できます。私のアプリはアプリストアを経由しませんでしたが、ここに記載されていないAPIに問題があるとは思いません。このソリューションの賢い部分は、UIView階層をトラバースし、UIScrollViewを使用していることです。どちらも完全にコーシャです。
Rolf Hendriks、2013

0

bouncesプロパティを調べますUIScrollView。アップルのドキュメントをクーズ:

プロパティの値がYES(デフォルト)の場合、スクロールビューは、コンテンツの境界に到達するとバウンスします。視覚的に跳ねることは、スクロールがコンテンツの端に達したことを示します。値がの場合NO、スクロールはバウンドせずにコンテンツ境界ですぐに停止します。

適切なものを使用していることを確認してくださいUIScrollView。の階層がどのように見えるかわかりませんUIWebViewが、スクロールビューはの子ではなく親になる可能性がありUIWebViewます。


0

UIWebViewスクロールを無効にするには、次のコード行を使用できます。

[ObjWebview setUserInteractionEnabled:FALSE];

この例でObjWebviewは、タイプはUIWebViewです。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.