Dừng UIWebView từ nảy nảy theo chiều dọc?


225

Có ai biết làm thế nào để ngăn UIWebView nảy lên theo chiều dọc không? Ý tôi là khi người dùng chạm vào màn hình iphone của họ, kéo ngón tay xuống và trang web hiển thị một chỗ trống phía trên trang web tôi đã tải?

Tôi đã xem xét các giải pháp có thể sau đây, nhưng không có giải pháp nào phù hợp với tôi:

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

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

Làm cách nào để ngăn UIScrollView nảy lên theo chiều ngang?


1
Tôi hy vọng bạn đã xem xét ý nghĩa khả dụng của việc vô hiệu hóa tính năng đó. Đó là vì một lý do. Điều đó nói rằng, tôi cũng tò mò, làm thế nào bạn làm điều đó.
Michael Haren

Cách tôi nhúng nó vào ứng dụng của mình, nó dường như xuất hiện với một số yếu tố chế độ xem khác mà tôi có và lần duy nhất nó không xuất hiện là khi xảy ra hiện tượng nảy .... Chắc chắn là một điểm tốt!
Công viên Brad

Câu trả lời:


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

... Có vẻ hoạt động tốt.

Nó cũng sẽ được chấp nhận vào App Store.

Cập nhật : trong iOS 5.x + có một cách dễ dàng hơn - UIWebViewcó thuộc scrollViewtính, vì vậy mã của bạn có thể trông như thế này:

webView.scrollView.bounces = NO;

Cùng đi cho WKWebView.


Nó hoạt động. Không yêu cầu phân lớp và nếu Apple thay đổi cấu trúc phân cấp UIWebView, thì nó không bị sập.
leolobato

2
Khắc phục sự cố này dường như chỉ hoạt động trong Trình mô phỏng hệ điều hành 4.1 của tôi, không phải trên iPhone hệ điều hành 3.1.3 của tôi. Có ai biết nếu sửa lỗi này chỉ hoạt động trên các phiên bản hệ điều hành cụ thể?
Dan J

@MirukRusin - Làm thế nào bạn có thể đảm bảo rằng ứng dụng này sẽ được chấp nhận dựa trên ba dòng mã? : P
Moshe

@Mirek - Bạn đã bỏ lỡ quan điểm của tôi. Làm thế nào để bạn biết rằng không có gì khác trong ứng dụng sẽ bị từ chối?
Moshe

6
Điều này làm việc tốt cho tôi. Để thuận tiện, tôi đã thêm một danh mục để UIWebViewtôi có thể gọi [webView setBounces:NO]bất cứ nơi nào tôi muốn.
zekel

46

Tôi đã xem xét một dự án giúp dễ dàng tạo các ứng dụng web dưới dạng các ứng dụng có thể cài đặt đầy đủ trên iPhone có tên QuickConnect và tìm thấy một giải pháp hoạt động, nếu bạn không muốn màn hình của mình có thể cuộn được, trong trường hợp của tôi Tôi đã không.

Trong bài viết dự án / blog được đề cập ở trên, họ đề cập đến một chức năng javascript mà bạn có thể thêm vào để tắt tính năng nảy, về cơ bản thực hiện theo cách này:

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

Nếu bạn muốn xem thêm về cách họ triển khai nó, chỉ cần tải xuống QuickConnect và kiểm tra xem .... Nhưng về cơ bản, tất cả những gì nó gọi là javascript khi tải trang ... Tôi đã thử đặt nó vào đầu tài liệu của mình, và nó có vẻ hoạt động tốt.


Câu trả lời này là cách chính xác để dừng cuộn dọc nội dung trong UIWebView.
Jessedc

3
Bạn có thể đã đưa ra toàn bộ câu trả lời, trước tiên tôi không muốn tải xuống toàn bộ mã nguồn của một ứng dụng khác và thậm chí tôi không thể tìm thấy nó. Câu trả lời của bạn dựa trên một trang web khác giống như khi bạn trả lời.
Jonathan.

Câu trả lời này & câu trả lời được chấp nhận ở trên dường như đôi khi được yêu cầu. Trong trường hợp của tôi, tôi thấy rằng nếu chế độ xem web chưa được tải, thì độ nảy sẽ ở đó cho đến khi JS ở trên thực sự được tải vào hệ thống. Vì vậy, câu trả lời dường như là điều này và câu trả lời được chấp nhận ở trên là cả hai, đôi khi, được yêu cầu.
Kalle

3
như Jessedc đã nói, điều này sẽ dừng cuộn dọc, không chỉ nảy. điều đó có nghĩa là nếu bạn có div hoặc do đó yêu cầu cuộn, nó sẽ không cuộn.
đáng nhớ

18

Vâng tất cả những gì tôi đã làm để thực hiện điều này là:

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 

}

Hoạt động tốt với tôi ... Ngoài ra, câu trả lời được đánh dấu cho câu hỏi này là câu trả lời mà Apple sẽ từ chối nếu bạn sử dụng nó trong ứng dụng iphone của mình.


3
Đây là cách tốt nhất và đơn giản nhất. Đây phải là câu trả lời được chấp nhận! +1
PostCodeism

3
Đừng làm điều đó - ứng dụng của tôi đã bị từ chối vì sử dụng dòng đầu tiên. Lãng phí quá nhiều thời gian cho tôi. tôi đã sử dụng [[webView.subview lastObject] setScrollEnables: NO]; và apple nói rằng đó là một API riêng và do đó đã từ chối nó; hiện đang gửi lại nhưng đã sử dụng "userInteractionEnables: NO" vì tôi không cần bất kỳ liên kết hoạt động nào trong ứng dụng.
Veeru

UIWebView kế thừa từ UIView. UIView có các cuộc phỏng vấn tài sản. Riêng tư ở đây là gì? Tất cả những điều này bạn có thể tìm thấy trên developer.apple.com
Valerii Pavlov

3
Tôi có một cái gì đó giống như 4 ứng dụng trên kho ứng dụng bằng cách này. Ứng dụng của bạn rõ ràng đã bị từ chối vì một lý do khác. đây không phải là một API riêng.
Zigglzworth

4
Đây thực sự không phải là một ý tưởng tốt. Bạn đang dựa vào thực tế rằng đây UIScrollViewlà cuộc phỏng vấn đầu tiên UIWebViewcó thể là trường hợp hiện tại nhưng điều này có thể dễ dàng thay đổi trong các bản cập nhật (thậm chí là nhỏ) trong tương lai cho iOS hoặc các cấu hình cụ thể. Bạn thực sự nên forlặp đi lặp lại subviewsđể thực sự tìm thấy UIScrollView(nó thực sự không phải là nhiều công việc và ít nhất bạn được đảm bảo để có được UIScrollViewvà không làm hỏng chương trình của bạn ...
Jonathan Ellis

17

Trong SDK iOS 5, bạn có thể truy cập trực tiếp vào chế độ xem cuộn được liên kết với chế độ xem web thay vì lặp qua các lần xem xét của nó.

Vì vậy, để vô hiệu hóa 'nảy' trong chế độ xem cuộn, bạn có thể sử dụng:

myWebView.scrollView.bounces = NO;

Xem tài liệu tham khảo lớp UIWebView .

(Tuy nhiên, nếu bạn cần hỗ trợ các phiên bản SDK trước 5.0, bạn nên làm theo lời khuyên của Mirek Rusin .)



9

Cảnh báo. Tôi đã sử dụng setAllowsRubberBanding: trong ứng dụng của mình và Apple đã từ chối nó, nói rằng các chức năng API không công khai không được phép (trích dẫn: 3.3.1)


4

Trong Swift để vô hiệu hóa bị trả lại

webViewObj.scrollView.bounces = false

3

Phương pháp của Brad làm việc cho tôi. Nếu bạn sử dụng nó, bạn có thể muốn làm cho nó an toàn hơn một chút.

id scrollView = [yourWebView.subview objectAt Index: 0];
if ([scrollView phản hồiToSelector: @selector (set ALLowsRubberBanding :)])
{
    [scrollView PerformanceSelector: @selector (set ALLowsRubberBanding :) withObject: NO];
}

Nếu apple thay đổi một cái gì đó thì độ nảy sẽ quay trở lại - nhưng ít nhất ứng dụng của bạn sẽ không gặp sự cố.


3

Chỉ trên iOS5 nếu bạn có kế hoạch cho phép người dùng thu phóng nội dung của chế độ xem web (ei: nhấn đúp), cài đặt thoát không đủ. Bạn cũng cần đặt các thuộc tính alwaysBounceHTHER và alwaysBounceV vertical thành NO, khác khi chúng thu nhỏ (một lần chạm hai lần khác ...) để mặc định nó sẽ bật lại.


2

Tôi đã duyệt qua bộ sưu tập các cuộc phỏng vấn của UIWebView và đặt nền của chúng thành [UIColor blackColor], cùng màu với nền của trang web. Chế độ xem vẫn sẽ bị trả lại nhưng nó sẽ không hiển thị nền màu xám đen xấu xí đó.


1
Trên thực tế, đây là một điều khá tệ, bởi vì nếu Apple thay đổi nội bộ của UIWebView, thì vụ hack này có thể bị phá vỡ.
bpapa

2

Theo tôi thì UIWebView có UIScrollView. Bạn có thể sử dụng API tài liệu cho việc này, nhưng nảy được đặt cho cả hai hướng, không phải riêng lẻ. Đây là trong các tài liệu API. UIScrollView có thuộc tính thoát, do đó, một cái gì đó như thế này hoạt động (không biết nếu có nhiều hơn một cuộn xem):

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

Tôi đã rất khó chịu khi phát hiện ra rằng UIWebView không phải là một chế độ xem cuộn, vì vậy tôi đã tạo một lớp con tùy chỉnh để có được ở chế độ xem cuộn của chế độ xem web. Suclass này chứa một chế độ xem cuộn để bạn có thể tùy chỉnh hành vi của chế độ xem web của bạn. Phần cuối của lớp này là:

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

}

Sau đó, khi bạn tạo chế độ xem web tùy chỉnh, bạn có thể tắt tính năng nảy với:

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

Đây là một cách mục đích chung tuyệt vời để tạo chế độ xem web với hành vi cuộn tùy chỉnh. Chỉ có một vài điều cần chú ý:

  • như với bất kỳ chế độ xem nào, bạn cũng sẽ cần ghi đè - (id) initWithCoder: nếu bạn sử dụng nó trong Trình tạo giao diện
  • ban đầu khi bạn tạo chế độ xem web, kích thước nội dung của nó luôn giống với kích thước của khung nhìn. Sau khi bạn cuộn web, kích thước nội dung thể hiện kích thước của nội dung web thực trong chế độ xem. Để giải quyết vấn đề này, tôi đã thực hiện một vài thứ hacky - gọi -setContent Offerset: CGPointMake (0,1) hoạt hình: CÓ để buộc một thay đổi không đáng chú ý sẽ đặt kích thước nội dung phù hợp của chế độ xem web.

2

Đi qua điều này để tìm kiếm một câu trả lời và cuối cùng tôi đã may mắn nhận được câu trả lời của riêng mình bằng cách nhầm lẫn. tôi đã làm

[[webview scrollView] setBounces:NO];

va no đa hoạt động.


2

Điều này làm việc cho tôi và cũng rất đẹp (tôi đang sử dụng phonegap với webView)

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

hoặc là

[[webView scrollView] setScrollEnabled:NO];

1

Tôi đã thử một cách tiếp cận hơi khác để ngăn các đối tượng UIWebView cuộn và nảy: thêm một trình nhận dạng cử chỉ để ghi đè các cử chỉ khác.

Dường như, UIWebView hoặc chương trình phụ của trình điều khiển cuộn của nó sử dụng trình nhận dạng cử chỉ pan riêng để phát hiện cuộn người dùng. Nhưng theo tài liệu của Apple, có một cách hợp pháp để ghi đè một trình nhận dạng cử chỉ này với một trình nhận dạng cử chỉ khác. Giao thức UIGestureRecognizerDelegate có một phương thức cử chỉ phương thức : nênRecognizeSim đồng thờiWithGestureRecognizer: - cho phép kiểm soát hành vi của bất kỳ nhận dạng cử chỉ va chạm nào.

Vì vậy, những gì tôi đã làm là

trong phương thức viewDidLoad của trình điều khiển xem:

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

Sau đó, phương thức ghi đè cử chỉ:

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

Tất nhiên, phương thức ủy nhiệm này có thể giúp tôi phức tạp hơn trong một ứng dụng thực tế - chúng tôi có thể vô hiệu hóa các trình nhận dạng khác một cách chọn lọc, phân tích otherGestureRecognizer.view và đưa ra quyết định dựa trên quan điểm của nó.

Và cuối cùng, để hoàn thiện, phương pháp chúng tôi đã đăng ký như một trình xử lý pan:

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

nó có thể trống nếu tất cả những gì chúng ta muốn là hủy cuộn và nảy của chế độ xem web hoặc nó có thể chứa mã riêng của chúng ta để thực hiện loại chuyển động pan và hoạt hình mà chúng ta thực sự muốn ...

Cho đến nay tôi chỉ đang thử nghiệm tất cả những thứ này, và nó dường như đang hoạt động ít nhiều như tôi muốn. Mặc dù vậy, tôi chưa thử gửi bất kỳ ứng dụng nào cho iStore. Nhưng tôi tin rằng tôi đã không sử dụng bất cứ thứ gì không có giấy tờ cho đến nay ... Nếu có ai tìm thấy nó khác, xin vui lòng thông báo cho tôi.


1

Đây là hai giải pháp tiềm năng mới hơn. Rõ ràng, bạn có thể sử dụng jqtouch hoặc pastrykit để vô hiệu hóa cuộn. Tuy nhiên, tôi không có những thứ này để làm việc. Bạn có thể có thẩm quyền hơn.

tắt cuộn dọc

đào vào pastrykit




0

Một trong những cuộc phỏng vấn UIWebViewnên là a UIScrollView. Đặt thuộc tính của nó scrollEnabledthành NOvà chế độ xem web sẽ bị vô hiệu hóa cuộn hoàn toàn.

Lưu ý: về mặt kỹ thuật, đây là sử dụng API riêng và do đó ứng dụng của bạn có thể bị từ chối hoặc gặp sự cố trong các bản phát hành HĐH trong tương lai. Sử dụng @tryrespondsToSelector


Tôi đã thử nó và nó bị lỗi khi tôi thử nó ... Thật kỳ lạ, tôi có thể truy cập và thiết lập scrollView.bounces (không có hiệu lực), nhưng khi tôi thử và đặt scrollEnables, nó bị lỗi ...
Brad

Tôi tin rằng cuộc phỏng vấn được gọi là UIScroller, không phải UIScrollView. UIScroller là lớp không có giấy tờ và không được hỗ trợ, có nhiều điểm chung với UIScrollView, nhưng bạn không thể phụ thuộc vào mọi thứ hoạt động theo cùng một cách và không thay đổi trong các phiên bản HĐH trong tương lai.
Marco

Tôi đã làm điều này trên một ứng dụng iPad (không phải iPhone) chạy iOS 3.2 và có thể lấy UIScrollView ra khỏi UIWebView của tôi. Tôi đã tùy chỉnh thành công chế độ xem này để thay đổi nhiều hơn chỉ là hành vi nảy của nó để tôi có thể làm chứng cho hoạt động này trên iPad. Ứng dụng của tôi không đi qua cửa hàng ứng dụng, nhưng tôi không nghĩ sẽ có vấn đề với API không có giấy tờ ở đây. Phần thông minh cho giải pháp này là bạn chỉ cần duyệt qua hệ thống phân cấp UIView và sử dụng UIScrollView - cả hai đều hoàn hảo hơn.
Rolf Hendriks

0

Nhìn vào bouncestài sản của UIScrollView. Bỏ các tài liệu của Apple:

Nếu giá trị của thuộc tính là YES(mặc định), chế độ xem cuộn sẽ bị trả lại khi gặp ranh giới của nội dung. Bouncing trực quan chỉ ra rằng cuộn đã đạt đến một cạnh của nội dung. Nếu giá trị là NO, cuộn dừng ngay lập tức tại ranh giới nội dung mà không bị nảy.

Hãy chắc chắn rằng bạn đang sử dụng đúng UIScrollView. Tôi không chắc hệ thống phân cấp trông như thế nào đối với một UIWebView, nhưng chế độ xem cuộn có thể là cha mẹ, không phải là con của UIWebView.


0

Để tắt tính năng UIWebViewcuộn, bạn có thể sử dụng dòng mã sau:

[ObjWebview setUserInteractionEnabled:FALSE];

Trong ví dụ này, ObjWebviewlà loại UIWebView.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.