May 23, 2008

UIWebView Example Code

Posted in iPhone development tagged , , , , , , , , at 5:22 pm by tetontech

The information in this posting is old and has been superseded by the information in a new post.

The information and source code covered in this posting has been expanded on and is included in a downloadable framework called QuickConnectiPhone. Take a look at this posting about version 1.5 to learn more more.

There is also a development roadmap

It appears that a great need exists for a straight forward example of how to use the UIWebView class. The purpose of this example is to show how to use it from within a class that can be initialized by an application delegate class. I have included both the header and source file code so that you can see how this can be done. The complete source for these files as well as additional code and helps can be found at the QuickConnect site. Go to the downloads section and grab the QuickConnectiPhone framework.
If you wish to have your view scale in response to pinch gestures you will need to uncomment the
//aWebView.scalesPageToFit = YES;
line.
This class also is listening to acceleration events and making a call to a javascript function which you would need to write when an acceleration event occurs. I hope this is helpful. I am working on some QuickConnectiPhone documentation right now and hope to have an introduction video available soon.

To see a quick discription of the QuickConnectiPhone framework see this post.

The header file:
/*
Copyright 2007 Lee S. Barney

This file is part of QuickConnectiPhoneHybrid.

QuickConnectiPhoneHybrid is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

QuickConnectiPhoneHybrid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with QuickConnectiPhoneHybrid. If not, see .
*/

#import

#define kAccelerometerFrequency .001 //Hz

@interface BrowserViewController : UIViewController {
UIWebView *webView;
}

@property (nonatomic, retain) UIWebView *webView;

 

@end

The class file:
/*
Copyright 2007 Lee S. Barney

This file is part of QuickConnectiPhoneHybrid.

QuickConnectiPhoneHybrid is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

QuickConnectiPhoneHybrid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with QuickConnectiPhoneHybrid. If not, see .
*/
#import "BrowserViewController.h"

@implementation BrowserViewController

@synthesize webView;

- (id)init
{
/*
if (self = [super init]) {
}
*/
return self;
}

- (void)loadView
{
NSLog(@”loading view”);

// the base view for this view controller
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
contentView.backgroundColor = [UIColor blueColor];

// important for view orientation rotation
contentView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
self.view = contentView;
self.view.autoresizesSubviews = YES;
//create a frame that will be used to size and place the web view
CGRect webFrame = [[UIScreen mainScreen] applicationFrame];
webFrame.origin.y -= 20.0; // shift the display up so that it covers the default open space from the content view
UIWebView *aWebView = [[UIWebView alloc] initWithFrame:webFrame];
self.webView = aWebView;
//aWebView.scalesPageToFit = YES;
aWebView.autoresizesSubviews = YES;
aWebView.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
//set the web view and acceleration delagates for the web view to be itself
[aWebView setDelegate:self];
//determine the path the to the index.html file in the Resources directory
NSString *filePathString = [[NSBundle mainBundle] pathForResource:@”index” ofType:@”html”];
//build the URL and the request for the index.html file
NSURL *aURL = [NSURL fileURLWithPath:filePathString];
NSURLRequest *aRequest = [NSURLRequest requestWithURL:aURL];
//load the index.html file into the web view.
[aWebView loadRequest:aRequest];

//add the web view to the content view
[contentView addSubview:webView];

[aWebView release];
[contentView release];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations.
return YES;
}
– (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{

if(fromInterfaceOrientation == UIInterfaceOrientationPortrait){
NSString* result = [webView stringByEvaluatingJavaScriptFromString:@”rotate(0)”];
//NSString a = *result;
NSLog(result);

}
else{
[webView stringByEvaluatingJavaScriptFromString:@”rotate(1)”];
}

//[self.webView sizeToFit];
//CGRect curBounds = [[UIScreen mainScreen] bounds];
//[self.webView setBounds:self.origViewRectangle];
//[[UIScreen mainScreen] bounds]]
//NSLog(@”orienting”);
}

- (void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{

NSString* javaScriptCall = [NSString stringWithFormat:@”accelerate(%f, %f, %f)”, acceleration.x, acceleration.y, acceleration.z];

[webView stringByEvaluatingJavaScriptFromString:javaScriptCall];
//Use a basic low-pass filter to only keep the gravity in the accelerometer values
//_accelerometer[0] = acceleration.x * kFilteringFactor + _accelerometer[0] * (1.0 – kFilteringFactor);
//_accelerometer[1] = acceleration.y * kFilteringFactor + _accelerometer[1] * (1.0 – kFilteringFactor);
//_accelerometer[2] = acceleration.z * kFilteringFactor + _accelerometer[2] * (1.0 – kFilteringFactor);
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning]; // Releases the view if it doesn’t have a superview.
// Release anything that’s not essential, such as cached data.
}
– (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
NSLog(@”An error happened during load”);
}
– (void)webViewDidStartLoad:(UIWebView *)webView{
NSLog(@”loading started”);
}
– (void)webViewDidFinishLoad:(UIWebView *)webView{
NSLog(@”finished loading”);
}

- (void)dealloc
{
[super dealloc];
}

 

@end

About these ads

14 Comments »

  1. Cory said,

    This was the most useful example i have ever seen!! Thanks for helping out!

    • Alphans said,

      hello Cory,
      can you please tell me, what is the above file extension and how do i load it to iphone?

  2. Carina said,

    I can’t tell you for how long I’ve been fighting now with the UIWebView. Thanks a lot for this example, it was extremely helpful!

  3. Nune said,

    You are super hero!
    Thank you so much for helping out on fighting with UIWebView :)

  4. tetontech said,

    I’m glad it is helpful.

    If you would like some more ideas check out the other posts on this blog. I have been creating a framework around this example that may be of help. It is called QuickConnectiPhone

  5. georges said,

    This code helped me a ton. Thanks for posting!

  6. layne said,

    Any suggestions on how to force the webview to start to be in landscape mode?
    If I add an entry called UIInterfaceOrientation and assign it a value of UIInterfaceOrientationLandscapeRight in the info.plist. The status bar starts in landscape but the webview is still in portrait. Also if I start the app while holding it in landscape the shifting (webFrame.origin.y -= 20.0) of the screen gets all messed up. Thanks for sharing the code.

    • tetontech said,

      Layne,

      Are you using the code from this post or from the QuickConnectiPhone framework?

      Lee

  7. Layne said,

    I am using the code just from this post
    thanks

    • tetontech said,

      That implementation is naive. If you want to see a better implementation you could see how it is done in the NativeFooter example in the QuickConnectiPhone download. Look on the bottom right of the blog for a link to the download site.

      Most specifically you will want to look in the *FooterVCO.m files and in the QuickConnectViewController.m file for the code in the shouldAutorotateToInterfaceOrientation and didAutorotateToInterfaceOrientation methods.

      When the device starts up these rotate methods are called regardless of the orientation. Essentially what I do is hide all displayed footers in the should method and display them again in the did method.

      The HideFooterVCO and ShowFooterVCO files should show you what I had to do to get this to work correctly.

      If you need further help let me know.

      Lee

      • Mosiah said,

        Hi Lee,

        Have you run into the following issue? Know of any better solutions?

        http://discussions.info.apple.com/message.jspa?messageID=11434305

        I’m experiencing similar issues when loading a viewcontroller containing a UIWebView in the background. I call this method to trigger the load:

        – (void)loadViewInMainThread:(UIViewController*)viewController {
        [viewController view];
        }

        The view is a UIView containing a UIWebView. But for some reason when loaded this way the UIWebView does not respond to the orientation of the device until the device is rotated while the UIWebView is visible, after which it responds to device rotations whether or not the view is visible.

        I’ve tried a number of hacks, but found nothing that solves the problem well. Any ideas? I can provide a full sample app showing the problem if it helps. Thanks for all your hard work in this difficult area!

        – Mosiah

      • tetontech said,

        Let me see if I understand your issue. You want the web view to detect orientation when it is displayed and it is not. Is that correct?

      • Mosiah said,

        Correct. The webview should:

        – Be loaded in the background (i.e. loaded while another webview is displayed)
        – Be displayed with the correct dimensions/layout for the current orientation
        – Relayout its content with new dimensions whenever the device orientation changes, whether or not the view is visible during the orientation change.

        Here’s a very simple sample project demonstrating the problem:

        http://dl.dropbox.com/u/10203/TabBarWithBackgroundLoadedWebView.zip

        To reproduce the issue:

        1. Open, build and run the project in XCode.
        2. Before doing anything, rotate the device or simulator window to landscape.
        3. Tap the second tab.
        4. Notice that the initial dimensions of the webview content that was loaded in the background are incorrect for the current device orientation.
        5. Also notice that until the background loaded view is displayed in portrait mode, it does not respond to orientation changes, no matter how many times you rotate the device back and forth.

        Sample code that loads the second view controller view in the background, found in WebViewTabController:

        – (void)viewDidLoad {
        [super viewDidLoad];
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@”http://touch.facebook.com”]]];
        NSArray *controllers = self.tabBarController.viewControllers;
        UIViewController *controller = [controllers objectAtIndex:1];
        [controller view];
        }

        Maybe there’s a better way to trigger the loading of the view in the background so it picks up on orientation changes, and I just haven’t stumbled upon it. After spending the better part of a weekend looking for a solution for this, I’m throwing my hands in the air.

        Thanks again for sharing your time and expertise! :-)

  8. Amit Patel said,

    Thanks to Poster …

    This Code is Very Helpful For Me..thanks again..:)


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 318 other followers

%d bloggers like this: