views:

594

answers:

7

I'm trying to disable scrolling for a UIWebView and the only way i found is using this way:

#import <objc/runtime.h>

id scroller = [[Webview subviews] lastObject];
int count;
Method *method = class_copyMethodList([scroller class], &count);
int i;
for (i=0; i<count; i++) {
    if (strcmp(method_getName(method[i]), "setScrollingEnabled:") == 0)
        break;
}
IMP test = method_getImplementation(method[i]);
test(scroller, @selector(setScrollingEnabled:), NO);

Is this considered to be an illegal way of using the iPhone SDK? Can this cause my application to be rejected for the App store?

A: 

It might be questionable, but not a cause for rejection as long as you have a fallback behavior when/if the method can not be found. There are worse abuses that have passed.

PeyloW
A: 

Well, maybe they think you did it another way, like take the contents of an offscreen UIWebView and displayed it in a plain UIIMage view, or take the HTML content of a page restrict its size and render it in a UIWebView.

mahboudz
I'd like to know how to "take the contents of an offscreen UIWebView and displayed it in a plain UIIMage view". Any tips?
jm
You can use -renderInContext. If you need more details, start a new questions since it is hard to post code in comments.
mahboudz
+3  A: 

wouldn't it be a lot simpler to do this:

if ([scroller respondsToSelector: @selector(setScrollingEnabled:)]) [scroller setScrollingEnabled: NO]

This avoids any of the potential method calls they might scan your binary for (not sure how they verify 'legality'). It's still not 100% kosher, but definitely safer.

Ben Gottlieb
+1  A: 

Yes this is considered illegal. I actually received a 'warning' saying that setSCrollingEnabled was part of a private framework. They approved the app but said that I needed to remove this call for the next update I submit.

Alex Argo
+1  A: 

I just got my app rejected because of using setScrollingEnabled, so BEWARE!

Their message: "The non-public API that is included in your application is setScrollingEnabled"

Andre
+1  A: 

If the method isn't in the .h file, it's private. It's a pretty simple rule. The fact you need to perform any runtime "shenanigans" for a simple message send should be telling.

Will Hartung
A: 

This works –

UIScrollView *scrollView = [[myWebView subviews] lastObject]; scrollView.scrollEnabled = FALSE;

This fixes the problem, while also keeping the links click-able, any scrollViews it’s embedded in scrollable, and uses only public API’s.

I found that the javascript solutions prevented the WebViews from working correctly if it was embedded in a UIScrollView and setting userInteractionEnabled to false prevented links in the webView from being click-able.

Tobin