UIWebView가 세로로 "튀는"것을 중지 하시겠습니까?


225

누구든지 UIWebView가 세로로 튀는 것을 막는 방법을 알고 있습니까? 사용자가 iPhone 화면을 터치하고 손가락을 아래쪽으로 끌면 웹뷰에 내가로드 한 웹 페이지 위에 빈 자리가 표시됩니까?

나는 다음과 같은 가능한 해결책을 보았지만 그중 어느 것도 나를 위해 일하지 않았다.

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
해당 기능을 비활성화하면 사용성에 미치는 영향을 고려했으면합니다. 이유가 있습니다. 그건 당신이 어떻게 할 지 궁금합니다.
Michael Haren

내 앱에 포함시키는 방식은 내가 가지고있는 다른보기 요소와 함께 보이지 않는 것처럼 보이며, 나타나지 않는 유일한 시간은 바운스가 발생하는 시점입니다 .... 확실히 좋은 지적입니다!
Brad Parks

답변:


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

... 잘 작동하는 것 같습니다.

App Store에도 적용됩니다.

업데이트 :에 아이폰 OS 5.x의 +가 쉬운 방법이야 - UIWebViewscrollView코드는 다음과 같이 할 수 있도록 속성을 :

webView.scrollView.bounces = NO;

동일합니다 WKWebView.


효과가있다. 서브 클래 싱이 필요하지 않으며 Apple이 UIWebView 계층 구조를 변경하더라도 충돌하지 않아야합니다.
leolobato

2
이 수정은 OS 3.1.3 iPhone이 아닌 OS 4.1 Simulator에서만 작동하는 것 같습니다. 이 수정 프로그램이 특정 OS 버전에서만 작동하는지 아는 사람이 있습니까?
Dan J

@MirukRusin-이 앱이 세 줄의 코드를 기반으로 허용되는지 어떻게 확인할 수 있습니까? : P
Moshe

@Mirek-당신은 내 요점을 놓쳤다. 앱의 어떤 것도 거부되지 않는다는 것을 어떻게 알 수 있습니까?
Moshe

6
이것은 나를 위해 잘 작동했습니다. 편의상 원하는 곳에 UIWebView전화를 걸 [webView setBounces:NO]수 있도록 카테고리를 추가했습니다 .
zekel

46

QuickConnect 라는 iPhone에서 완전한 설치 가능한 응용 프로그램으로 웹 응용 프로그램을 쉽게 만들 수있는 프로젝트를 찾고 있었고 화면을 스크롤 할 수 없도록하려는 경우 작동하는 솔루션을 찾았습니다. 나는하지 않았다.

위에서 언급 한 프로젝트 / 블로그 게시물에서 수신 거부 기능을 해제하기 위해 추가 할 수있는 자바 스크립트 기능에 대해 언급했습니다.이 기능은 본질적으로 다음과 같이 요약됩니다.

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

구현 방법에 대한 자세한 내용을 보려면 QuickConnect를 다운로드하여 확인하십시오 ... 그러나 기본적으로 페이지로드시 해당 자바 스크립트를 호출하기 만하면됩니다. 잘 작동하는 것 같습니다.


이 답변은 UIWebView 내에서 콘텐츠의 세로 스크롤을 중지하는 올바른 방법입니다.
Jessedc

3
전체 답변을 제공 할 수 있습니다. 먼저 다른 앱의 전체 스컬스 코드를 다운로드하고 싶지 않으며 찾을 수 없습니다. 귀하의 답변은 답변 할 때와 동일한 다른 웹 사이트를 사용합니다.
조나단.

이 답변과 위의 답변은 때때로 필요한 것 같습니다. 필자의 경우 웹보기가 아직로드되지 않은 경우 위의 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 

}

나를 위해 잘 작동합니다 ... 또한,이 질문에 대한 틱 된 대답은 당신이 당신의 아이폰 애플 리케이션에서 사용하는 경우 애플이 거부 할 것입니다.


3
이것이 가장 좋고 가장 간단한 방법입니다. 이것이 정답입니다! +1
PostCodeism

3
그렇게하지 마십시오-첫 번째 줄을 사용하여 앱이 거부되었습니다. 나를 위해 너무 많은 시간을 낭비했다. [[webView.subviews lastObject]를 사용했습니다. setScrollEnabled : NO]; 애플은 개인 API라고해서 거부했다. 앱에 활성 링크가 필요하지 않으므로 지금 다시 제출하려고하지만 "userInteractionEnabled : NO"를 사용했습니다.
Veeru

UIWebView는 UIView에서 상속합니다. UIView에는 속성 하위 뷰가 있습니다. 여기서 사적인 것은 무엇입니까? 이 모든 내용은 developer.apple.com에서 찾을 수 있습니다.
Valerii Pavlov

3
이것을 사용하여 앱 스토어에 4 개의 앱이 있습니다. 다른 이유로 앱이 명확하게 거부되었습니다. 이것은 개인 API가 아닙니다.
Zigglzworth

4
이것은 실제로 좋은 생각이 아닙니다. 당신 UIScrollView은 현재의 첫 번째 서브 뷰가 현재로서는 사실 UIWebView일 수도 있지만 iOS 또는 특정 구성에 대한 향후 (사소한) 업데이트에서 쉽게 변경 될 수 있다는 사실에 의존하고 있습니다. 당신은 정말해야 할 for이상 반복을 subviews실제로 찾기 위해 UIScrollView정말 그 많은 일을하지 않고 적어도 당신이 얻을 보장 ( UIScrollView... 프로그램을 충돌하지
조나단 엘리스

17

iOS 5 SDK에서는 하위보기를 반복하지 않고 웹보기와 연관된 스크롤보기에 직접 액세스 할 수 있습니다.

따라서 스크롤보기에서 '수신 거부'를 비활성화하려면 다음을 사용할 수 있습니다.

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에서는 사용자가 웹뷰 콘텐츠를 확대 (예 : 두 번 탭) 할 수있는 경우에만 바운스 설정이 충분하지 않습니다. alwaysBounceHorizontal 및 alwaysBounceVertical 속성도 NO로 설정해야합니다. 그렇지 않으면 기본으로 확대 / 축소 (또 다른 두 번 탭)하면 다시 바운스됩니다.


2

UIWebView의 하위 뷰 모음을 탐색하고 배경을 웹 페이지 배경과 동일한 색상 인 [UIColor blackColor]로 설정했습니다. 보기는 여전히 튀어 나오지만 그 추한 회색 배경은 표시되지 않습니다.


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가 스크롤보기가 아니라는 것을 알게되어 화가 났으므로 웹보기의 스크롤보기를 얻기 위해 사용자 정의 하위 클래스를 만들었습니다. 이 suclass에는 스크롤보기가 포함되어 있으므로 웹보기의 동작을 사용자 정의 할 수 있습니다. 이 수업의 핵심은 다음과 같습니다.

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

}

그런 다음 맞춤 웹보기를 만들 때 다음을 사용하여 수신 거부를 사용 중지 할 수 있습니다.

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

이것은 사용자 정의 가능한 스크롤 동작으로 웹보기를 만드는 훌륭한 범용 방법입니다. 주의해야 할 몇 가지 사항이 있습니다.

  • 모든보기와 마찬가지로-(id) initWithCoder :을 재정의해야합니다. 인터페이스 빌더에서 사용하는 경우
  • 웹보기를 처음 만들 때 내용 크기는 항상보기 프레임 크기와 같습니다. 웹을 스크롤 한 후 컨텐츠 크기는보기 내의 실제 웹 컨텐츠 크기를 나타냅니다. 이 문제를 해결하기 위해 해킹을 시도했습니다. -setContentOffset : CGPointMake (0,1) animated : YES를 호출하여 알 수없는 변경으로 인해 웹보기의 적절한 콘텐츠 크기를 설정했습니다.

2

이 답을 찾는 것을 가로 질러 왔고 결국 나는 엉망으로 내 자신의 답을 얻었습니다. 내가 했어

[[webview scrollView] setBounces:NO];

그리고 효과가있었습니다.


2

이것은 저에게도 효과가 있었고 아름답습니다 (webView와 함께 phonegap을 사용하고 있습니다)

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

또는

[[webView scrollView] setScrollEnabled:NO];

1

UIWebView 객체가 스크롤 및 수신 거부 되는 것을 방지하기 위해 약간 다른 접근법을 시도했습니다 . 다른 제스처를 무시하기 위해 제스처 인식기를 추가하십시오.

그것은 보인다 있는 UIWebView 또는 스크롤의 서브 뷰는 사용자가 스크롤을 감지하는 자신의 팬 제스처 인식기를 사용합니다. 그러나 Apple의 문서에 따르면 한 제스처 인식기를 다른 제스처 인식기를 재정의하는 합법적 인 방법이 있습니다. 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를 분석 하고 뷰에 따라 결정을 내릴 수 있습니다.

그리고 마지막으로 완전성을 기하기 위해 팬 처리기로 등록한 방법은 다음과 같습니다.

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

웹보기의 스크롤 및 수신 거부를 취소하는 것만 큼 비워 두거나 실제로 원하는 팬 모션 및 애니메이션을 구현하는 자체 코드를 포함 할 수 있습니다 ...

지금까지 나는이 모든 것들을 실험하고 있으며, 내가 원하는대로 다소 작동하는 것 같습니다. 그래도 아직 iStore에 앱을 제출하지 않았습니다. 하지만 지금까지 문서화되지 않은 것을 사용하지 않았다고 생각합니다. 다른 사람이 발견하면 알려주십시오.


1

두 가지 새로운 잠재적 솔루션이 있습니다. 분명히 jqtouch 또는 pastrykit을 사용하여 스크롤을 비활성화 할 수 있습니다. 그러나 나는 이것들이 작동하지 않았다. 더 유능 할 수도 있습니다.

세로 스크롤 끄기

생과자에 파기




0

의 하위 견해 중 하나는 UIWebView이어야합니다 UIScrollView. scrollEnabled속성을로 설정 NO하면 웹보기에서 스크롤이 완전히 비활성화됩니다.

참고 : 이것은 기술적으로 개인 API를 사용하므로 향후 OS 릴리스에서 앱이 거부되거나 중단 될 수 있습니다. 사용 @tryrespondsToSelector


이것을 시도해 보았을 때 오류가 발생합니다 ... 이상하게도 scrollView.bounces에 액세스하여 설정할 수 있지만 (효과는 없습니다), scrollEnabled를 시도하고 설정하면 오류가 발생합니다 ...
Brad Parks

하위 뷰는 UIScrollView가 아니라 UIScroller라고합니다. UIScroller는 문서화되지 않은 지원되지 않는 클래스로 UIScrollView와 공통점이 많지만, 동일한 방식으로 작동하고 향후 OS 버전에서 변경되지 않는 모든 것에 의존 할 수는 없습니다.
Marco

iOS 3.2를 실행하는 iPad (iPhone이 아닌) 앱 에서이 작업을 수행했으며 UIWebView에서 UIScrollView를 가져올 수있었습니다. 이보기를 사용자 정의하여 수신 거부 동작 이상의 것을 변경하여 iPad에서이 작업을 증언 할 수 있습니다. 내 앱이 앱 스토어를 거치지 않았지만 문서화되지 않은 API에 문제가 있다고 생각하지 않습니다. 이 솔루션의 영리한 부분은 UIView 계층 구조를 순회하고 UIScrollView를 사용한다는 것입니다.
Rolf Hendriks

0

bounces속성을 살펴보십시오 UIScrollView. Apple 문서 정리

속성 값이 YES(기본값) 인 경우 스크롤 경계가 내용의 경계에 도달하면 바운스됩니다. 수신 거부는 스크롤이 컨텐츠의 가장자리에 도달했음을 나타냅니다. 값이 NO인 경우 수신 거부없이 컨텐츠 경계에서 즉시 스크롤이 중지됩니다.

올바른를 사용하고 있는지 확인하십시오 UIScrollView. 의 계층 구조가 확실하지 UIWebView않지만 스크롤 뷰는의 하위가 아닌 상위가 될 수 있습니다 UIWebView.


0

UIWebView스크롤 을 비활성화하려면 다음 코드 줄을 사용할 수 있습니다.

[ObjWebview setUserInteractionEnabled:FALSE];

이 예에서는 ObjWebview유형 UIWebView입니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.