Remove form assistant from keyboard in iPhone standalone web app - iphone

Is it possible to remove the form assistant from the iPhone popup keyboard in a standalone web app? I know the general consensus is that it's not possible in Mobile Safari, but a standalone app runs in a UIWebView, and functions differently in several ways (example), so I'm hoping this might be possible.
You can see it here right above the keyboard:
The Previous and Next buttons cycle between <form> inputs. But I have a single <input> element, so they are disabled. The Done button hides the keyboard, but since I have a height-flexible <ul> (that takes up the space between the keyboard and the <input>), and I have nothing else on this page, it serves no purpose.
On a tiny screen, and with almost half the screen taken up by the keyboard, the 44 pixels that make up this toolbar are a huge waste of space (an entire <li>'s worth).
Native iOS apps can remove it, so I know it's at least possible on the phone, I've just not discovered a way to do it in a web app. This is from the Facebook app and the page is very similar to mine:
I've tried using an <input> not wrapped in a <form> and also using a contenteditable <div>, but the results were the same. There are several custom -webkit- styles to control various aspects of the web app interface, but they are poorly documented, and a search turned up nothing on this.
Any way to remove the form assistant in a web app?

If you app is a web app wrapped in a native Objetive-C app this is possible by manipulating Keyboard views.
first, register to receive the keyboardDidShow notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
this will call the following method when keyboard shows up:
-(void)keyboardDidShow:(NSNotification*)notif
{
NSArray *array = [[UIApplication sharedApplication] windows];
for (UIWindow* wind in array) {
for (UIView* currView in wind.subviews) {
if ([[currView description] hasPrefix:#"<UIPeripheralHostView"]) {
for (UIView* perView in currView.subviews) {
if ([[perView description] hasPrefix:#"<UIWebFormAccessory"]) {
[perView setHidden:YES];
}
}
}
}
}
}
this method goes over the views on screen looking for the form assistant and hiding it.
NOTE: Apple probably won't reject this, as i've seen it being used by Facebook etc, but this technique might break in upcoming iOS releases.

All signs point to this not being possible, including several questions here.

You can do a category of UIView and "override" the behaviour of addSubview: like the example below. Call the method "exachangeMethods" from your applicationDidFinishLaunching of your AppDelegate.
#import "UIView+util.h"
#import <objc/runtime.h>
#implementation UIView (util)
// Swaps our custom implementation with the default one
// +load is called when a class is loaded into the system
+ (void) exchangeMethods
{
SEL origSel = #selector(addSubview:);
SEL newSel = #selector(customAddSubview:);
Class viewClass = [UIView class];
Method origMethod = class_getInstanceMethod(viewClass, origSel);
Method newMethod = class_getInstanceMethod(viewClass, newSel);
method_exchangeImplementations(origMethod, newMethod);
}
- (void) customAddSubview:(UIView *)view{
if( [[view description]rangeOfString:#"<UIWebFormAccessory"].location!=NSNotFound) {
return;
}
// This line at runtime does not go into an infinite loop
// because it will call the real method instead of ours.
return [self customAddSubview:view];
}
#end

Related

Keyboard shows then immediately hides itself when showing MFMessageComposeViewController

I am building a PhoneGap app using Cordova 2.2 for IOS. I am experiencing some bizarre behavior when calling out to a native obj-c plugin I have written to show the MFMessageComposeViewController.
The setup is very simple - I have a tap event attached to a UI element, that when pressed, will make a call to my PhoneGap plugin, pass with it a number and a text message, then show the MFMessageComposeViewController with the parameters pre-populated.
My javascript looks like this:
$(document).bind('deviceready', function(){
$(".theButton").tap(function(){
cordova.exec(function(){}, function() {}, "PhoneGapSms", "SendSms", [db.getItem("profile_sms"), db.getItem("profile_emergency")]);
});
});
And my obj-c code looks like this:
- (void)SendSms:(CDVInvokedUrlCommand*)command
{
CDVInvokedUrlCommand* myCommand = command;
MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init];
NSString* body = [command.arguments objectAtIndex:0];
NSString* toRecipientsString = [command.arguments objectAtIndex:1];
if(body != nil)
picker.body = body;
if(toRecipientsString != nil)
[picker setRecipients:[ toRecipientsString componentsSeparatedByString:#","]];
picker.messageComposeDelegate = self;
[self.viewController presentModalViewController:picker animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[picker release];
}
So, all in all, very simple stuff.
My Problem is this:
When my iPhone is plugged into my Mac and the app is run from XCode, the Message Composer overlay appears great, with my values pre-populated. Image below demonstrating the SMS interface appears fine while plugged into XCode:
When my iPhone is unplugged from my Mac, and the app is run from the spring board, the Overlay slides up, the keyboard begins to slide up, then immediately slides down - making it impossible to type or send the message. This is what it looks like when not attached to the Mac/Xcode - the keyboard begins to slide up then immediately slides down (~ < 1 sec) leaving the following interface:
I can't for the life of me figure out what would cause the keyboard to hide when not running from XCode, but work perfectly well when it is.
Is there any way to 'force' the keyboard to display, or possibly put the whole modalviewcontroller as first responder in some form or fashion?
Any suggestions are appreciated!
Edit:
The keyboard WILL appear again if you click in the contact area
You must add MessageUI.framework to your Xcode project and include a
#import <MessageUI/MessageUI.h> in your header file.
try this code may be its helpful to you..
[self presentModalViewController:picker animated:YES];
//[self becomeFirstResponder];//try picker also instead of self
Also Refer this bellow tutorial and also check demo..
new-tutorial-developing-and-architecting-a-phonegap-application
SMSComposer
i hope this help you...
I encountered these symptoms with a Sencha Touch 2.2 and Cordova 2.6.0 setup (specifically, iOS 6+ devices).
The issue was with the web framework stealing focus away from the native SMS Composer modal, typically occurring after the first SMS Composer modal had been successfully displayed and closed.
A event.preventDefault() and event.stopPropagation() call once the event had been fired (or event.stopEvent() in Sencha land) resolved this.
Hope this helps,
-James
First: The most likely culprit, without seeing your code, is that your parent (presenting) view controller may have an action in its viewWillDisappear or viewDidDisappear that is affecting who has the "first" responder. These methods get called when presenting a view controller modally. It may be behaving differently on the simulator than the device due to timing - often really close timing conditions are different on the ARM device and the i386 processor.
Second: Does anywhere in your app register for the UIKeyboardWillShowNotification or the UIKeyboardDidShowNotification? If so, put breakpoints in the methods that are called as a result - it's possible some other controller in your view hierarchy is interfering with this one.
To answer your question...
Is there any way to 'force' the keyboard to display, or possibly put the whole modalviewcontroller as first responder in some form or fashion?
No to both. The only way to make the keyboard display is to call the becomeFirstResponder method of the input view. Since Apple doesn't expose the text view, you cannot send it messages. Setting the modalViewController as first responder would be setting the wrong object.
I found the same type of issue But Not Sure it will Solve your problem or not Just Have a Look on the Following Links :
1. http://community.phonegap.com/nitobi/topics/keyboard_is_not_triggerd_in_my_ios_build
2. https://github.com/phonegap/build/issues/31
If its not Solving your issue then you can Download the Sample code Here.
Link: https://github.com/phonegap/phonegap-plugins/tree/master/iPhone/SMSComposer

How to add Pop up Button in UIWebView

The deafult pop up is get opened when I long press the music play option in any url from UIWebView.
I Want to add one more button in the pop up..Is it possible to do it..
Like I want to add FETCH button.
And Can I make changes in the default pop up functioning which is OPEN and COPY. shown below
I come to know that by google -
First of all, you really can’t add additional menu items to the default ones of the standard contextual menu. But you can switch off the contextual menu using a certain CSS property. So the solution would be to switch off the default menu and implement your own from scratch. And to implement your own contextual menu, you have to first catch the tab-and-hold gesture, get the coordinates of the finger on the screen, translate these coordinates into the coordinate system of the web page and finally look for the HTML elements at this location.
NEW ANSWER:
Looks like this is what we want, here:
https://stackoverflow.com/a/3198220/700471
OLD ANSWER:
Okay, after some research, here's the deal:
What you describe in your question seems accurate:
First of all, you really can’t add additional menu items to the
default ones of the standard contextual menu. But you can switch off
the contextual menu using a certain CSS property. So the solution
would be to switch off the default menu and implement your own from
scratch. And to implement your own contextual menu, you have to first
catch the tab-and-hold gesture, get the coordinates of the finger on
the screen, translate these coordinates into the coordinate system of
the web page and finally look for the HTML elements at this location.
So you are planning on implementing your own popover controller with contextual menu--fine, I won't get into that at all, I will assume you know how to do that.
What your question seems to be is, how do you take a long-tap gesture in the UIWebView and transform it into the coordinates of the webpage to find the DOM element that was selected, and use that as a context from which to generate your popover menu.
What I found was this, specifically this with this line of code:
NSString *js = [NSString stringWithFormat:#"document.elementFromPoint(%f, %f).innerHTML", touchPoint.x, touchPoint.y];
That looks like the JS you would need to figure out what element had just been long-pressed, and of course you would need to do some figure-figure to see if it was a link and execute your context menu from there, but that's not something I've looked into.
Some further thoughts:
Probably the easiest course would be to attach a UILongPressGestureRecognizer to your UIWebView (this can be done easily in a nib) and make sure that the "Sent Action" points to an appropriate IBAction on your ViewController. (I suppose you could use the delegate outlet as well, but I have never needed to do that.)
In any case, you can use the locationOfTouch:inView: method of your gesture recognizer, and the view you will probably want to use will be the UIWebView's content view, which I believe you can get with something like myWebView.scrollView.subviews[0] (or the objectAtIndex: variation if you are not using the new array index subscripts).
Anyway, I think I have provided enough to answer your question.
EDIT:
Okay, so you are still having trouble with this, so I went and made a test project and got it to work. One thing that is slightly annoying about this is that WebKit somehow adds a "buffer" area around objects in the DOM, meaning that if you touch slightly next to a link it will still highlight, but when you use the JS command elementFromPoint it doesn't do that, so you kinda have to touch more carefully to trigger the popup using this method. But, it works.
I made a blank project with the "single view" template, and threw a UIWebView into the xib, pointed its delegate outlet to File's Owner. Then I put a UILongPressGestureRecognizer into the xib, attached to the UIWebView. I set its delegate as File's Owner, and set its selector outlet to the longPressDetected IBAction in File's Owner. I also unchecked "Canceled in View" in the recognizer's properties in Interface Builder.
Here is the code for the view controller.
Interface:
//
// WVTViewController.h
// WebViewTest
//
#import <UIKit/UIKit.h>
#interface WVTViewController : UIViewController <UIWebViewDelegate, UIGestureRecognizerDelegate>
#property (nonatomic, weak) IBOutlet UIWebView *myWebView;
#property (nonatomic) BOOL didFirstLoad;
- (IBAction)longPressDetected:(id)sender;
#end
Implementation:
//
// WVTViewController.m
// WebViewTest
//
#import "WVTViewController.h"
#interface WVTViewController ()
#end
#implementation WVTViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Just load google.
NSURL *theURL = [NSURL URLWithString:#"http://www.google.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:theURL];
[self.myWebView loadRequest:request];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if (!self.didFirstLoad) {
// Disable the default contextual menu.
[webView stringByEvaluatingJavaScriptFromString:#"document.body.style.webkitTouchCallout='none';"];
}
}
// Called by the gesture recognizer.
- (IBAction)longPressDetected:(UILongPressGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateBegan) {
NSLog(#"Long press detected.");
CGPoint webViewCoordinates = [sender locationInView:self.myWebView];
NSLog(#"WebView coordinates are: %#", NSStringFromCGPoint(webViewCoordinates));
// Find the DOM element
NSString *locatorString = [NSString stringWithFormat:#"document.elementFromPoint(%f, %f).innerHTML", webViewCoordinates.x, webViewCoordinates.y];
NSString *result = [self.myWebView stringByEvaluatingJavaScriptFromString: locatorString];
NSLog(#"Element Found: %#", result);
}
}
// Necessary or the gesture recognizer won't call the IBAction.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
#end
As I said, I tested the above code and it works fine. You can of course change up your JS and use something other than innerHTML, such as tagName or href or whatever you like. Multiple checks may be necessary for what you're trying to do, possibly with queued JS commands (which would be lame), unless you could JSON-stringify the DOM object, pass it back to the Objective-C, convert to native objects and perform your checks in that environment--but, I'm no JS pro and I'm not going to investigate that.
As a note, I was a bit surprised that the coordinates that worked for elementFromPoint were the touch coordinates within the UIWebView itself. I had rigged up a whole block of code that iterated through myWebView.scrollView.subviews and found the content view, then called locationOfTouch:inView: on that view. But I was getting funky behavior, so on a hunch I used the webview coordinates and it worked fine, even on a big webpage when I was scrolled off to the side and down. I suspect that some kind of Apple-programmed behavior inside the webview may translate those coordinates. Possibly the JS's coordinate system is altered based on the way the content view is moved around inside the scrollview--that makes the most sense to me.
The proper and accurate way to answer this question is below link
http://www.icab.de/blog/2010/07/11/customize-the-contextual-menu-of-uiwebview/
you can fire the event with something like this:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if( navigationType == UIWebViewNavigationTypeLinkClicked )
{
// Handle your URL click here (open the popup menu)
// ...
return NO;
}
return YES;
}
don't forget to delegate the UIWebView

I'm just beginning Objective-C and I'm developing an iPhone app. I need some help with Objective-C

I'm 14 and developing my second iOS app: an iPhone version of the web-based chatroom I created for my school. I have very little knowledge of Objective-C and I need some help. This is a very basic app, where I have a UIWebView and a tool bar at the bottom of the view. The toolbar contains a text field and a "Send" button. I have the UIWebView working and pointing to the correct site, but I need two basic things:
1. I need the toolbar to reposition itself to the top of the keyboard when the text box is tapped, also resizing the UIWebView for the correct space.
and
2. I need to find a way to post the contents of my text field to my PHP script online when the "Send" button is tapped or the "Send" key on the keyboard is pressed.
Any help would be much appreciated!
Edit: Here are some screenshots of the app.
App screenshots.
You'll want to take a look at "Managing The Keyboard".
In essense what you want to do is have the delegate of the textfield deal with the keyboard notification "UIKeyboardWillShowNotification", and use the info which it will supply to move the toolbar into place, possibly with an animation.
---UPDATE---
Looking around a little, I found this:
iPhone Keyboard Covers UITextField
Lots of stuff to answer here!
Repositioning the toolbar
To reposition the toolbar you'll need to do a few things:
Get notified when the user starts using it
Resize your webview and move your toolbar
In order to get notified when the user taps on your text field you will need to:
Implement the UITextFieldDelegate protocol in your controller (most likely the main view controller).
Implement the delegate method -textFieldDidBeginEditing:.
Set your controller object as the text field's delegate.
UITextFieldDelegateProtocol Reference should explain this.
To resize your controls you will need to have them declared as IBOutlets and hook them up in interface builder. Your best bet for this is to read the Interface Builder Quick Start Guide.
Sending the data
Sending the data is going to be the trickier bit. A couple of things you could do:
Cheat and send the data as "GET" data by using a method like NSString's -initWithContentsOfURL: (something like this:)
NSString *chatString = [textField stringValue]; //get the chat string
NSString *encodedString = [chatString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]; //URL-encode any special characters
NSString *urlToRequest = [NSString stringWithFormat:#"http://mysite.com/chat.php?message=%#", encodedString];
NSURL *requestURL = [NSURL URLWithString:urlToRequest];
NSString *urlResult = [NSString stringWithContentsOfURL:requestURL];
By doing it this way you will be able to get the message in your php script like so:
$encoded_message = $_GET['message'];
$message = urldecode($encoded_message);
This is not the most robust way but for a high school project it should probably be fine.
The more robust way you could do it is by using the cocoa libraries intended for this. I won't delve into these details as it is quite complex and Apple's own developer documentation does a much better job of explaining it: URL Loading System Programming Guide
Edit: As per Hack Saw's post, using NSNotification to determine when the keyboard will show is better. By doing things the delegate way as I've described, you will only be notified when that particular text field is selected. Documentation on managing the keyboard can be found here: Text, Web, and Editing Programming Guide for iOS
This is a quick unfancy way to do move the toolbar up. I'm sure you'll be able to adapt it to your needs.
First you have to register for the keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
and then you move the toolbar up. Like this.
- (void)keyboardWillShow:(NSNotification *)notification {
if (keyboardShown) {
return;
}
NSDictionary* info = [notification userInfo];
// Get the size of the keyboard.
NSValue* aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGSize keyboardSize = [aValue CGRectValue].size;
CGRect currentFrame = self.toolbar.frame;
currentFrame.origin.y = currentFrame.origin.y - keyboardSize.height;
[UIView beginAnimations:#"ShowKeyboard" context:NULL];
[UIView setAnimationCurve:[[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
[UIView setAnimationDuration:[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
self.toolbar.frame = currentFrame;
[UIView commitAnimations];
keyboardShown = YES;
}
of course you have to create another method that will hide the keyboard, but this is basically the same as show keyboard, so I'll omit it.
To make things a little bit more easy you could make the toolbar and the webview subviews of a "content" view. You would then resize the height of the contentview and autoresizing will take care of the rest.
Oh and you should not resize the view just because of textFieldDidBeginEditing:. I don't know for the iphone, but it's possible to connect an external keyboard to the ipad. And you would resize the view without the keyboard showing up, leaving a big blank frame at the bottom.

iPhone dev: Increase scroll speed in UIWebView?

I have an app in which I render local HTML files in a UIWebView. The files, however, are sometimes large, and getting to where you want takes a long time with the default scroll speed. Is there any way to boost up the vertical scroll speed of a UIWebView?
In iOS 5 we can access the scrollView property of the UIWebView.
If you are targeting iOS 5+, you can simply call:
webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
Find a subview of UIWebView which is a UIScrollView, then set decelerationRate to UIScrollViewDecelerationRateNormal. This makes the UIWebView as fast as an ordinary UIScrollView.
In iOS 4/5, we can simply use the last subview of UIWebView.
UIScrollView *scroll = [webView.subviews lastObject];
if ([scroll isKindOfClass:[UIScrollView class]]) {
scroll.decelerationRate = UIScrollViewDecelerationRateNormal;
}
The default decelerationRate of UIWebView's UIScrollView is 0.989324, while UIScrollViewDecelerationRateFast is 0.99, and UIScrollViewDecelerationRateNormal is 0.998.
This method doesn't use any private API.
Search for a subview of UIWebView that responds to -setScrollDecelerationFactor: (it's UIScroller - a private class that's the only subview of UIScrollView). You'll find that it takes the same deceleration factors defined for the public UIScrollView class:
- (void)webViewDidFinishLoad:(UIWebView *)aView {
id decelerator = [aView viewWithSelector:#selector(setScrollDecelerationFactor:)];
[decelerator setScrollDecelerationFactor:UIScrollViewDecelerationRateNormal];
}
Note that the method I'm using viewWithSelector: is a method I defined in a category of UIView. Presumably, if UIWebView changes in future, my search will return nil and this method will become a no-op.
Have considered adding # tags into your html on significant boundaries?
You could actually use native UI to implement bookmarks or a ToC for easier navigation, or simply embed links to the appropriate targets right in your html.
If you 'speed up scrolling' your app is at risk of rejection for being non-standard, since it may confuse users who are used to webviews scrolling with a standard 'feel'.
Old question but these setting or trick really helped me even in 2018.
Follow these simple coding tricks to improve Android WebView Performance:
WebView mWebView = new WebView(this);
WebSettings settings = mWebView.getSettings();
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(false);
settings.setJavaScriptEnabled(true);
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);
mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
mWebView.setScrollbarFadingEnabled(true);
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
settings.setDomStorageEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else {
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

ScrollOffset in UIWebView?

I'm having a really hard time understanding delegates and object inheritance (if I may use this word) and I think I need a simple (or so I think) thing: catch scrollViewDidScroll event in UIWebView and get offset (basically, just to know if scroll is not on top/bottom, so I could hide navigation and tab bars).
Is there any way I could do it? I already using UIWebviewDelegate in my view controller to "shouldStartLoadWithRequest". Maybe I could some how use UIScrollViewDelegate too for scrollViewDidScroll? If yes, then how?
I really have trouble understanding delegates. I've red some articles, but still, in practice, I can't manage to use them.
Any help or info would be lovely.
Thank you in advance!
To retrieve scroll events on UIWebView I personnaly use this code to get the scrollview that is inside the UIWebView :
- (void) addScrollViewListener
{
UIScrollView* currentScrollView;
for (UIView* subView in self.myWebView.subviews) {
if ([subView isKindOfClass:[UIScrollView class]]) {
currentScrollView = (UIScrollView*)subView;
currentScrollView.delegate = self;
}
}
}
It's working. You can also use it to call [currentScrollView setContentOffset:offSet animated:YES]; The only problem may be not to pass Apple code checking. I don't know yet since I'm still in coding phase.
[UPDATE] The app with this code is in the app store for 4 months now and used by 40 000 users. I didn't have any trouble [UPDATE]
You can use the following methods to solve your problem.
For getting the pageOffset:
int pageYOffset = [[webViewObj stringByEvaluatingJavaScriptFromString:#"window.pageYOffset"] intValue];
For getting the total scroll height of a webpage:
int scrollHeight = [[webViewObj stringByEvaluatingJavaScriptFromString:#"document.documentElement.scrollHeight"] intValue];
For scrolling the webpage to a particular offset:
[webViewObj stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"document.body.scrollTop = %d",scrollHeight ]];
I made a modification to detect the class with isKindOfClass. Works - but may have issues with Apple code checking as stated above.
UIScrollView* currentScrollView;
for (UIView* subView in terms.subviews) {
if ([subView isKindOfClass:[UIScrollView class]]) {
NSLog(#"found scroll view");
currentScrollView = (UIScrollView *)subView;
currentScrollView.delegate = self;
}
}
Old thread, I know -
As of iOS 5.0 you can use
myAccountWebView.scrollview
to access content size and offset.
There is a scrolling view in the UIWebView, but it a) isn't a UIScrollView, and b) is something Apple considers a private implementation detail (and you should too). I only really have two suggestions:
File a bug with Apple asking them to expose more of the infrastructure of the web view, or at least add some more delegate methods by which we can be notified of these sorts of events.
Add some JavaScript code to your page that listens from scroll events, and notifies your app of them.
The basic foundation of #2 is to load a fake URL, and have your web view delegate process (and abort!) that load. (This question has come up a few times here on Stack Overflow.)
UPDATE:
As of iOS 5, there is now a public scrollView property on UIWebView that you can use to customize scrolling behavior. The exact view hierarchy of the web view remains an undocumented implementation detail, but this gives you a sanctioned way to access this piece of it.
It's a good question. UIWebView is not a subclass of UIScrollView, although I can see why one might think it is. That means using the UIScrollViewDelegate methods is not an option to do what you want, and the UIWebViewDelegate protocol does not respond to those scrolling event type of messages. I don't think there's an easy way to detect scrolling events in a web view.
I tired the delegate method and found it prevented the view from scrolling when the keyboard was shown. I found that by adding an observer you do not override the current delegate and will prevent you from effecting the webview performance.
for (UIView* subView in myAccountWebView.subviews) {
if ([subView isKindOfClass:[UIScrollView class]])
{
NSLog(#"found scroll view");
[((UIScrollView*)subView) addObserver:self forKeyPath:#"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}
}