Resolved Site Loads Differently in Web View on iPhone 6 Plus

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
300
14
I have a UIWebView that works correctly but the site loads some elements incorrectly on my iPhone 6 Plus. It looks like it's supposed to on every device simulator, on my 4S, my 5S, and in Safari on my 6 Plus. Any ideas what may be causing this?

I've provided images from my 5S and my 6 Plus. You can see that the 6 Plus has black text among other things wrong with it.
 

Attachments

Last edited:

ArtOfWarfare

macrumors G3
Nov 26, 2007
8,559
3,966
I have a UIWebView that works correctly but the site loads some elements incorrectly on my iPhone 6 Plus. It looks like it's supposed to on every device simulator, on my 4S, my 5S, and in Safari on my 6 Plus. Any ideas what may be causing this?

I've provided images from my 5S and my 6 Plus. You can see that the 6 Plus has black text among other things wrong with it.
Could we have the link to the site or minimal sample code that reproduces the problem?
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Few thoughts,

The web site may send different html depending on the user agent and it might not recognize the user agent for the web view on iPhone 6+, since iPhone 6+ is new. There might be a way to spoof the user agent, if that was the reason.

This web site is complicated and has lots of associated files (css, script, etc.) Maybe something isn't loading that is required. Do you have the delegate didFail method implemented and does anything fail to load? The black text and different size font points to a css failure, or failure of the website to recognize the iPhone 6+.

Is there any funny business in your code related to cookies, URL caching, URL Protocols etc.? IOW, is there something you're not telling us?

Can you try to build a simple app that has only one web view in it and loads this page to see how it looks?
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
300
14
I created a test app with a web view and it loads the site just fine. The app I'm having trouble with loads a RSS feed in a table view. When a row is selected, it shows that article in a web view, which is where I'm having problems on the 6 Plus.

Here is my didSelectRowAtIndexPath
Code:
[[webViewController webView]loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
        
        [self.navigationController pushViewController:webViewController animated:YES];
        
        RSSItem *entry = [[channel items]objectAtIndex:[indexPath row]];
        
        NSURL *url = [NSURL URLWithString:[entry link]];
        
        NSURLRequest *req = [NSURLRequest requestWithURL:url];
        
        [[webViewController webView]loadRequest:req];
        webViewController.hackyURL = url;
And here is WebViewController.h
Code:
#import <Foundation/Foundation.h>

@interface WebViewController : UIViewController <UIActionSheetDelegate, UIGestureRecognizerDelegate, UIWebViewDelegate, UISplitViewControllerDelegate, UIScrollViewDelegate>
{
    UIWebView *webView;
    NSURL *hackyURL;
}

@property (nonatomic, readonly)UIWebView *webView;
@property (nonatomic, retain) NSURL *hackyURL;
@property (nonatomic,retain)IBOutlet UIActivityIndicatorView *activityIndicator;
@property (strong, nonatomic) UIPopoverController *popover;
@property (strong, nonatomic) UIBarButtonItem *systemAction;

@end

And WebViewController.m
Code:
#import "WebViewController.h"
#import "TUSafariActivity.h"
#import "SVProgressHUD.h"
#import "UIViewController+ScrollingNavbar.h"
#import <QuartzCore/QuartzCore.h>

@implementation WebViewController
{
    UIActivityIndicatorView *loadingIndicator;
}

@synthesize webView=webView, hackyURL=hackyURL, activityIndicator, popover, systemAction;

- (void)loadView
{
    // Create an instance of UIWebView as large as the screen
    CGRect screenFrame = [[UIScreen mainScreen]applicationFrame];
    UIWebView *wv = [[UIWebView alloc]initWithFrame:screenFrame];
    webView = wv;
    NSLog(@"%@",webView.request.URL);
    // Tell web view to scale web content to fit within bounds of webview
    [wv setScalesPageToFit:YES];
    
    [self setView:wv];
}

- (UIWebView *)webView
{ 
    return (UIWebView *)[self view];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    webView.delegate = self;
    [webView.scrollView setDelegate:self];
    
    self.webView.opaque = NO;
    self.webView.backgroundColor = [UIColor darkGrayColor];
    
    CGFloat width = [[UIScreen mainScreen]bounds].size.width;
    CGFloat height = [[UIScreen mainScreen]bounds].size.height;
    
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
    {
        loadingIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(width / 2, height / 2, 37, 37)];
        loadingIndicator.center = CGPointMake(width / 2, height / 2 - 37);
    }
    else
    {
        loadingIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(334, 333, 37, 37)];
    }
    
    loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
    loadingIndicator.hidesWhenStopped = YES;
    [self.view addSubview:loadingIndicator];
    [loadingIndicator startAnimating];
    
    systemAction = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(showMenu)];
    self.navigationItem.rightBarButtonItem = systemAction;
}

// Do not allow user to navigate away from selected page
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL *url = request.URL;
    NSString *urlString = url.absoluteString;
    NSString *hackyURLString = hackyURL.absoluteString;
    
    //Check for your own url. You can use more advanced checking techniques of course :)
    NSRange range = [urlString rangeOfString:hackyURLString];
    if (range.location != NSNotFound)
        return YES;
    else
        return NO;
}

- (void)webViewDidStartLoad:(UIWebView *)wv
{
    NSLog(@"Did start load");
    
    [loadingIndicator startAnimating];
}

- (void)webViewDidFinishLoad:(UIWebView *)wv
{
    NSLog(@"Did finish load");
    
    [loadingIndicator stopAnimating];
}

-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    [loadingIndicator stopAnimating];
}
 
- (void)viewDidDisappear:(BOOL)animated
{
    [loadingIndicator stopAnimating];
}

- (void) showMenu
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
    {
        NSURL *urlToShare = hackyURL;
        NSArray *activityItems = @[urlToShare];
        TUSafariActivity *activity = [[TUSafariActivity alloc] init];
        
        __block UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:@[activity]];
        activityVC.excludedActivityTypes = @[UIActivityTypeAssignToContact, UIActivityTypePostToWeibo, UIActivityTypeSaveToCameraRoll];
        
        [self presentViewController:activityVC animated:YES completion:^{activityVC.excludedActivityTypes = nil; activityVC = nil;}];
    }
    else
    {
        NSURL *urlToShare = hackyURL;
        NSArray *activityItems = @[urlToShare];
        TUSafariActivity *activity = [[TUSafariActivity alloc] init];
        
        if (self.popover)
        {
            if ([self.popover isPopoverVisible])
            {
                [self.popover dismissPopoverAnimated:YES];
            }
            return;
        }
        
        UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:@[activity]];
        activityVC.excludedActivityTypes = @[UIActivityTypeAssignToContact, UIActivityTypePostToWeibo, UIActivityTypeSaveToCameraRoll];
        
        UIActivityViewController *__weak weakActivityVC = activityVC;
        
        activityVC.completionHandler = ^(NSString *service, BOOL completed)
        {
            weakActivityVC.excludedActivityTypes = nil;
            self.popover = nil;
        };
        
        self.popover = [[UIPopoverController alloc]initWithContentViewController:activityVC];
        [self.popover presentPopoverFromBarButtonItem:systemAction permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }
}

@end
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Few comments,

I guess creating the simple test app was a great idea :rolleyes:

I'm going to predict that some of your code is preventing this web page from loading correctly. I think it's the code in shouldStartLoadWithRequest:

I would start by commenting out that entire method. If that fixes the problem you should log the URLs it's trying to load and then figure out a better way to filter out the URLs to prevent the user from navigating away.

If that doesn't fix it I'd start commenting out the code method by method to figure things out.

Why no NSLog in didFailLoadWithError: ?

I would personally change the code flow so that the view controller has a NSURL property and it gets loaded into the web view inside viewDidLoad. That's a more normal code flow of loading up a web view. Probably the way you're doing it is OK but I would change it. I don't know if view controllers or views can be unloaded due to memory warnings any more. In the old days if that happened and your view controller was unloaded you needed to set up the view contents in viewDidLoad or it wouldn't work when the view controller was reloaded.

Web pages can cause webViewDidStartLoad: and webViewDidFinishLoad: to be called more than one time. Normally the number each is called is the same as the other. When I've done something like you show I increment a counter in webViewDidStartLoad: and decrement it in webViewDidFinishLoad: When the counter is zero in webViewDidFinishLoad: I know the web page is finished loading. Like many aspects of networking, logging what happens is the most reliable way to find these things out. You should have log statements in all the callbacks. Believe me UIWebview can do some unexpected things.
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
300
14
Removing shouldStartLoadWithRequest: did not fix it. I've commented out each method and there is no change in the way the site is displayed.
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
300
14
I would personally change the code flow so that the view controller has a NSURL property and it gets loaded into the web view inside viewDidLoad. That's a more normal code flow of loading up a web view. Probably the way you're doing it is OK but I would change it.

I did this with a new view controller and the results were the same.
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
What is that business with loading about:blank? I would remove that and just load the URL to the web page.

Does shouldStartLoadWithRequest: get called multiple times?

Does didFailLoadWithError: get called?

You might want to uninstall/reinstall the app. It's possible that there is something in the web cache that is causing this.
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
300
14
What is that business with loading about:blank? I would remove that and just load the URL to the web page.

You might want to uninstall/reinstall the app. It's possible that there is something in the web cache that is causing this.
I replaced the about:blank with
Code:
[[webViewController webView] stringByEvaluatingJavaScriptFromString:@"document.open();document.close()"];
I'm doing it so that if the user goes back to the table view to select a different article, the web view doesn't show the last url viewed while loading the new one.

I uninstalled/reinstalled the app and it is rendering the site like it should now.

Thanks for all the help!