UIWebView dikey olarak “sıçrar” durdurmak için?


225

Herkes bir UIWebView dikey olarak sıçrayan durdurmak nasıl biliyor mu? Bir kullanıcı iphone ekranına dokunduğunda, parmağını aşağı doğru sürüklediğinde ve web görünümü yüklediğim web sayfasının üstünde boş bir nokta gösterdiğinde mi?

Aşağıdaki olası çözümlere baktım, ancak hiçbiri benim için çalışmadı:

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

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

Bir UIScrollView öğesinin yatay olarak sıçramasını nasıl durdurabilirim?


1
Umarım bu özelliği devre dışı bırakmanın kullanılabilirlik sonuçlarını incelemişsinizdir. Orada bir sebep var. Ben de bunu nasıl yapacağınızı merak ediyorum dedi.
Michael Haren

Benim app gömülü şekilde, görünüşte sahip diğer bazı görünüm elemanları ile görünür, ve görünmüyor tek zaman sıçrama olduğunda .... Kesinlikle iyi bir nokta olsa!
Brad Parks

Yanıtlar:


424
for (id subview in webView.subviews)
  if ([[subview class] isSubclassOfClass: [UIScrollView class]])
    ((UIScrollView *)subview).bounces = NO;

... iyi çalışıyor gibi görünüyor.

App Store'a da kabul edilecektir.

Güncelleme : iOS 5.x + orada daha kolay bir yolu var - UIWebViewvardır scrollViewkod aşağıdaki gibi bakmak, böylece özelliği:

webView.scrollView.bounces = NO;

Aynı şey geçerli WKWebView.


İşe yarıyor. Alt sınıflama gerekmez ve Apple UIWebView hiyerarşisini değiştirirse çökmemelidir.
leolobato

2
Bu düzeltme, OS 3.1.3 iPhone'umda değil, yalnızca OS 4.1 Simulator'ımda çalışıyor gibi görünüyor. Bu düzeltmenin yalnızca belirli işletim sistemi sürümlerinde çalışıp çalışmadığını bilen var mı?
Dan J

@MirukRusin - Bu uygulamanın üç kod satırına göre kabul edileceğini nasıl garanti edebilirsiniz? : P
Moshe

@Mirek - Demek istediğimi kaçırdın. Uygulamadaki hiçbir şeyin reddedileceğini nasıl anlarsınız?
Moshe

6
Bu benim için iyi çalıştı. Kolaylık sağlamak için, istediğim her yeri UIWebViewarayabilmem için bir kategori ekledim [webView setBounces:NO].
zekel

46

İPhone'da QuickConnect adlı tam teşekküllü yüklenebilir uygulamalar olarak web uygulamaları oluşturmayı kolaylaştıran bir projeye bakıyordum ve ekranınızın hiç kaydırılabilir olmasını istemiyorsanız çalışan bir çözüm buldum. Ben yapmadım.

Yukarıda belirtilen proje / blog gönderisinde, zıplamayı kapatmak için ekleyebileceğiniz bir javascript işlevinden bahsediyorlar, bu da esasen buna bağlı:

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

Nasıl uyguladıkları hakkında daha fazla görmek istiyorsanız, sadece QuickConnect'i indirin ve kontrol edin .... Ama temelde tek yaptığı şey, sayfa yüklemesinde javascript'i çağırmak ... Sadece belgemin başına koymaya çalıştım, ve iyi çalışıyor gibi görünüyor.


Bu yanıt, bir UIWebView içindeki içeriğin dikey kaydırılmasını durdurmanın doğru yoludur.
Mart'ta Jessedc

3
Tüm cevabı vermiş olabilirsiniz, öncelikle başka bir uygulamanın bütün bir belası kodunu indirmek istemiyorum ve hatta bulamıyorum. Cevabınız, yanıtladığınız web sitesinin aynısı olan başka bir web sitesine dayanıyor.
Jonathan.

Bu cevap ve yukarıdaki kabul edilen cevap zaman zaman gerekli görünmektedir. Benim durumumda, web görünümü henüz yüklenmemiş olsaydı, yukarıdaki JS gerçekten sisteme yüklenene kadar bounciness orada olacağını buldum. Bu yüzden cevap, bu ve yukarıdaki kabul edilen cevabın zaman zaman gerekli olduğu gibi görünüyor.
Kalle

3
Jessedc'in dediği gibi, bu sadece sıçramayı değil, dikey kaydırmayı durduracaktır. Bu, bölme gerektiren div veya daha fazlasına sahip olduğunuzda kaydırma yapmayacağı anlamına gelir.
20'de 32:

18

Peki bunu başarmak için tek yaptığım:

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 

}

Benim için iyi çalışıyor ... Ayrıca, bu sorunun işaretli cevabı, iPhone uygulamanızda kullanırsanız Apple'ın reddedeceği sorudur.


3
Bu en iyi ve en basit yoldur. Bu kabul edilen cevap olmalı! +1
PostCodeism

3
Bunu yapmayın - uygulamam ilk satırı kullandığından dolayı reddedildi. Benim için çok zaman harcadım. [[webView.subviews lastObject] setScrollEnabled: NO] kullandım; ve elma bunun özel bir API olduğunu ve bu nedenle reddettiğini söyledi; şimdi yeniden göndermek üzereyim ama app herhangi bir aktif bağlantı gerekmez çünkü "userInteractionEnabled: NO" kullanılır.
Veeru

UIWebView, UIView'den devralınır. UIView'in mülk alt görüşleri var. Burada özel olan nedir? Tüm bunları developer.apple.com'da bulabilirsiniz
Valerii Pavlov

3
Bunu kullanarak uygulama mağazasında 4 uygulama gibi bir şey var. Uygulamanız başka bir nedenden dolayı açıkça reddedildi. bu özel bir API değil.
Zigglzworth

4
Bu gerçekten iyi bir fikir değil. Sen gerçeği dayanarak konum UIScrollViewilk Subview olan UIWebViewiyi şimdilik durumda olabilir ama bu kolayca gelecekte (hatta küçük) iOS veya belirli yapılandırmaları güncellemeleri içinde değişebilir hangi. Gerçekten bulmak için gerçekten bir foryineleme yapmalısınız (gerçekten çok fazla iş değil ve en azından programınızı almanız ve programınızı çökertmemeniz ...subviewsUIScrollViewUIScrollView
Jonathan Ellis

17

İOS 5 SDK'sında, bir web görünümü ile ilişkili kaydırma görünümüne alt görünümlerini yinelemek yerine doğrudan erişebilirsiniz.

Dolayısıyla, kaydırma görünümünde 'sıçramayı' devre dışı bırakmak için şunları kullanabilirsiniz:

myWebView.scrollView.bounces = NO;

UIWebView Sınıfı Referansına bakın .

(Ancak SDK'nın 5.0'dan önceki sürümlerini desteklemeniz gerekiyorsa Mirek Rusin'in tavsiyelerine uymalısınız .)



9

Uyarı. Uygulamamda setAllowsRubberBanding: kullandım ve Apple, genel olmayan API işlevlerine izin verilmediğini belirterek reddetti (alıntı: 3.3.1)


4

Swift'te sekmeleri devre dışı bırakmak için

webViewObj.scrollView.bounces = false

3

Brad'in yöntemi benim için çalıştı. Kullanırsanız, biraz daha güvenli hale getirmek isteyebilirsiniz.

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

Elma bir şeyi değiştirirse, geri dönen geri gelir - ancak en azından uygulamanız çökmez.


3

İOS5'te yalnızca kullanıcıların web görünümü içeriğini yakınlaştırmasına izin vermeyi planlıyorsanız (ei: çift dokunma) hemen çıkma ayarı yeterli değildir. Ayrıca, her zamanBounceHorizontal ve alwaysBounceVertical özelliklerini NO olarak ayarlamanız gerekir, aksi takdirde uzaklaştırma yaptıklarında (başka bir çift dokunma ...) varsayılan olarak tekrar geri döner.


2

UIWebView'in alt görüntülerini topladım ve arka planlarını web sayfası arka planıyla aynı renkte [UIColor blackColor] olarak ayarladım. Görünüm hala sekecek ama o çirkin koyu gri arka planı göstermeyecek.


1
Aslında bu oldukça kötü bir şey, çünkü Apple UIWebView'in iç kısımlarını değiştirirse, bu saldırı kırılabilir.
bpapa

2

Bana UIWebView bir UIScrollView sahip gibi görünüyor. Bunun için belgelenmiş API'ları kullanabilirsiniz, ancak geri dönme ayrı ayrı değil, her iki yön için de ayarlanır. Bu, API belgelerinde bulunur. UIScrollView bir bounce özelliğine sahiptir, bu nedenle böyle bir şey çalışır (birden fazla kaydırma görüntüsü olup olmadığını bilmiyorum):

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 bir kaydırma görünümü olmadığını öğrenmek için rahatsız oldu, bu yüzden web görünümünün kaydırma görünümünde almak için özel bir alt sınıf yaptım. Bu sınıf, web görünümünüzün davranışını özelleştirebilmeniz için bir kaydırma görünümü içerir. Bu sınıfın ana hatları:

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

}

Ardından, özel bir web görünümü oluşturduğunuzda, sıçramayı aşağıdakilerle devre dışı bırakabilirsiniz:

customWebView.scrollView.bounces = NO; //(or customWebView.scrollView.alwaysBounceVertically = NO)

Bu, özelleştirilebilir kaydırma davranışı ile bir web görünümü oluşturmanın harika bir genel amaçlı yoludur. Dikkat edilmesi gereken birkaç şey var:

  • herhangi bir görünümde olduğu gibi, ayrıca initWithCoder'i de geçersiz kılmanız gerekir: Arayüz Oluşturucu'da kullanırsanız
  • başlangıçta bir web görünümü oluşturduğunuzda, içerik boyutu her zaman görünümün çerçevesinin boyutuyla aynıdır. Web'i kaydırdıktan sonra, içerik boyutu görünümdeki gerçek web içeriğinin boyutunu temsil eder. Bunu aşmak için, hacky bir şey yaptım - call -setContentOffset: CGPointMake (0,1) animated: EVET, web görünümünün uygun içerik boyutunu ayarlayacak fark edilmeyen bir değişikliği zorlamak için.

2

Bir cevap arayışıyla karşılaştım ve sonunda kendimi bir cevapla uğraştım. yaptım

[[webview scrollView] setBounces:NO];

ve işe yaradı.


2

Bu benim için çalıştı ve güzel de (webView ile telefon boşluğu kullanıyorum)

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

veya

[[webView scrollView] setScrollEnabled:NO];

1

UIWebView nesnelerinin kaydırılmasını ve sıçramasını önlemek için biraz farklı bir yaklaşım denedim : diğer hareketleri geçersiz kılmak için bir jest tanıyıcı ekleyerek.

Görünüşe göre, UIWebView veya onun kaydırma alt görünümü, kullanıcı kaydırmasını algılamak için kendi pan hareketi tanıyıcıyı kullanıyor. Ancak Apple'ın belgelerine göre, bir jest tanıyıcıyı diğeriyle geçersiz kılmanın meşru bir yolu var. UIGestureRecognizerDelegate protokolü bir yöntemi vardır gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer: - bir çarpışan hareket tanıyıcıları davranışını kontrol etmek için olanak sağlayan.

Yani, yaptığım şey

görünüm denetleyicisinin viewDidLoad yönteminde:

// 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]; 

ardından, jest geçersiz kılma yöntemi:

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

Tabii ki, bu temsilci yöntemi gerçek bir uygulamada beni daha karmaşık hale getirebilir - diğer tanıyıcıları seçici olarak devre dışı bırakabilir, otherGestureRecognizer.view öğesini analiz edebilir ve görünümüne göre karar verebiliriz .

Ve son olarak, bütünlük adına, pan işleyicisi olarak kaydettiğimiz yöntem:

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

İstediğimiz tek şey web görünümlerinin kaydırma ve sıçramasını iptal etmekse boş olabilir veya gerçekten istediğimiz pan hareketlerini ve animasyonlarını uygulamak için kendi kodumuzu içerebilir ...

Şimdiye kadar sadece tüm bu şeyleri deniyorum ve istediğim kadar az ya da çok çalışıyor gibi görünüyor. Yine de iStore'a herhangi bir uygulama göndermeyi denemedim. Ama şimdiye kadar belgelenmemiş hiçbir şey kullanmadığımı düşünüyorum ... Eğer başka türlü bulursa, lütfen beni bilgilendirin.





0

Alt görüntülerinden biri UIWebViewolmalıdır UIScrollView. Onun Set scrollEnabledmülkü NOve web görünümü tamamen devre dışı kaydırmak olacaktır.

Not: Bu teknik olarak özel bir API kullanıyor ve bu nedenle uygulamanız gelecekteki işletim sistemi sürümlerinde reddedilebilir veya çökebilir. Kullan @tryverespondsToSelector


Bunu denedim ve denediğimde hata veriyor ... Garip bir şekilde, scrollView.bounces'a (efektsiz) erişebilir ve ayarlayabilirim, ancak scrollEnabled'ı denediğimde ve ayarladığımda, hata veriyor ...
Brad Parks

Alt görünüme UIScrollView değil, UIScroller denir inanıyorum. UIScroller, UIScrollView ile çok ortak bir şey paylaşan belgelenmemiş ve desteklenmeyen bir sınıftır, ancak aynı şekilde çalışan ve gelecekteki işletim sistemi sürümlerinde değişmeyen her şeye güvenemezsiniz.
Marco

Bunu iOS 3.2 çalıştıran bir iPad (iPhone değil) uygulamasında yaptım ve UIWebView'imden bir UIScrollView alabildim. İPad'de bu çalışmaya tanıklık edebilmek için bu görünümü zıplayan davranışından daha fazlasını değiştirmek için başarıyla özelleştirdim. Uygulamam uygulama mağazasından geçmedi, ancak burada belgesiz API'lerle ilgili bir sorun olacağını düşünmüyorum. Bu çözümün akıllı kısmı, sadece bir UIView hiyerarşisinde dolaşmanız ve her ikisi de mükemmel bir şekilde koşer olan bir UIScrollView kullanmanızdır.
Rolf Hendriks

0

'In bouncesmülküne bakın UIScrollView. Apple dokümanlar hakkında bilgi:

Özelliğin değeri YES(varsayılan) ise, kaydırma görünümü içeriğin bir sınırıyla karşılaştığında geri döner. Görsel olarak sıçramak, kaydırmanın içeriğin bir kenarına ulaştığını gösterir. Değer ise NO, kaydırma hemen içerik sınırında sekmeden durur.

Doğru kullandığınızdan emin olun UIScrollView. Hiyerarşinin neye benzediğinden emin değilim UIWebView, ancak kaydırma görünümü, öğesinin alt öğesi değil, üst olabilir UIWebView.


0

UIWebViewKaydırmayı devre dışı bırakmak için aşağıdaki kod satırını kullanabilirsiniz:

[ObjWebview setUserInteractionEnabled:FALSE];

Bu örnekte ObjWebviewtiptir UIWebView.


0

webView.scrollView.scrollEnabled = HAYIR; webView.scrollView.bounces = HAYIR;

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.