i am trying to develop a app that will load a iAd like popup view that will show a webview with a image in it. what i mean is that it will load a JPG or PNG url in it. i successfully created that popup but webview in not showing image in it can anyone please debug my code. i will post it here.
MainViewController.m
-(IBAction)openPopupWithURL
{
[MTPopupWindow showWindowWithHTMLFile:#"http://URL/ad.php" insideView:self.view];
}
PopUpWindow.h
#import <Foundation/Foundation.h>
#interface MTPopupWindow : NSObject
{
UIView* bgView;
UIView* bigPanelView;
}
+(void)showWindowWithHTMLFile:(NSString*)fileName insideView:(UIView*)view;
#end
PopUpWindow.m
#import "MTPopupWindow.h"
#define kShadeViewTag 1000
#interface MTPopupWindow(Private)
- (id)initWithSuperview:(UIView*)sview andFile:(NSString*)fName;
#end
#implementation MTPopupWindow
/**
* This is the only public method, it opens a popup window and loads the given content
* #param NSString* fileName provide a file name to load a file from the app resources, or a URL to load a web page
* #param UIView* view provide a UIViewController's view here (or other view)
*/
+(void)showWindowWithHTMLFile:(NSString*)fileName insideView:(UIView*)view
{
[[MTPopupWindow alloc] initWithSuperview:view andFile:fileName];
}
/**
* Initializes the class instance, gets a view where the window will pop up in
* and a file name/ URL
*/
- (id)initWithSuperview:(UIView*)sview andFile:(NSString*)fName
{
self = [super init];
if (self) {
// Initialization code here.
bgView = [[[UIView alloc] initWithFrame: sview.bounds] autorelease];
[sview addSubview: bgView];
// proceed with animation after the bgView was added
[self performSelector:#selector(doTransitionWithContentFile:) withObject:fName afterDelay:0.1];
}
return self;
}
/**
* Afrer the window background is added to the UI the window can animate in
* and load the UIWebView
*/
-(void)doTransitionWithContentFile:(NSString*)fName
{
//faux view
UIView* fauxView = [[[UIView alloc] initWithFrame: CGRectMake(10, 10, 200, 200)] autorelease];
[bgView addSubview: fauxView];
//the new panel
bigPanelView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, bgView.frame.size.width, bgView.frame.size.height)] autorelease];
bigPanelView.center = CGPointMake( bgView.frame.size.width/2, bgView.frame.size.height/2);
//add the window background
UIImageView* background = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"popupWindowBack.png"]] autorelease];
background.center = CGPointMake(bigPanelView.frame.size.width/2, bigPanelView.frame.size.height/2);
[bigPanelView addSubview: background];
//add the web view
int webOffset = 10;
UIWebView* web = [[[UIWebView alloc] initWithFrame:CGRectInset(background.frame, webOffset, webOffset)] autorelease];
web.backgroundColor = [UIColor clearColor];
if ([fName hasPrefix:#"http"]) {
//load a web page
web.scalesPageToFit = YES;
[web loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString: fName]]];
} else {
//load a local file
NSError* error = nil;
NSString* fileContents = [NSString stringWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fName] encoding:NSUTF8StringEncoding error: &error];
if (error!=NULL) {
NSLog(#"error loading %#: %#", fName, [error localizedDescription]);
} else {
[web loadHTMLString: fileContents baseURL:[NSURL URLWithString:#"file://"]];
}
}
[bigPanelView addSubview: web];
//add the close button
int closeBtnOffset = 10;
UIImage* closeBtnImg = [UIImage imageNamed:#"popupCloseBtn.png"];
UIButton* closeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[closeBtn setImage:closeBtnImg forState:UIControlStateNormal];
[closeBtn setFrame:CGRectMake( background.frame.origin.x + background.frame.size.width - closeBtnImg.size.width - closeBtnOffset,
background.frame.origin.y ,
closeBtnImg.size.width + closeBtnOffset,
closeBtnImg.size.height + closeBtnOffset)];
[closeBtn addTarget:self action:#selector(closePopupWindow) forControlEvents:UIControlEventTouchUpInside];
[bigPanelView addSubview: closeBtn];
//animation options
UIViewAnimationOptions options = UIViewAnimationOptionTransitionFlipFromRight |
UIViewAnimationOptionAllowUserInteraction |
UIViewAnimationOptionBeginFromCurrentState;
//run the animation
[UIView transitionFromView:fauxView toView:bigPanelView duration:0.5 options:options completion: ^(BOOL finished) {
//dim the contents behind the popup window
UIView* shadeView = [[[UIView alloc] initWithFrame:bigPanelView.frame] autorelease];
shadeView.backgroundColor = [UIColor blackColor];
shadeView.alpha = 0.3;
shadeView.tag = kShadeViewTag;
[bigPanelView addSubview: shadeView];
[bigPanelView sendSubviewToBack: shadeView];
}];
}
/**
* Removes the window background and calls the animation of the window
*/
-(void)closePopupWindow
{
//remove the shade
[[bigPanelView viewWithTag: kShadeViewTag] removeFromSuperview];
[self performSelector:#selector(closePopupWindowAnimate) withObject:nil afterDelay:0.1];
}
/**
* Animates the window and when done removes all views from the view hierarchy
* since they are all only retained by their superview this also deallocates them
* finally deallocate the class instance
*/
-(void)closePopupWindowAnimate
{
//faux view
__block UIView* fauxView = [[UIView alloc] initWithFrame: CGRectMake(10, 10, 200, 200)];
[bgView addSubview: fauxView];
//run the animation
UIViewAnimationOptions options = UIViewAnimationOptionTransitionFlipFromLeft |
UIViewAnimationOptionAllowUserInteraction |
UIViewAnimationOptionBeginFromCurrentState;
//hold to the bigPanelView, because it'll be removed during the animation
[bigPanelView retain];
[UIView transitionFromView:bigPanelView toView:fauxView duration:0.5 options:options completion:^(BOOL finished) {
//when popup is closed, remove all the views
for (UIView* child in bigPanelView.subviews) {
[child removeFromSuperview];
}
for (UIView* child in bgView.subviews) {
[child removeFromSuperview];
}
[bigPanelView release];
[bgView removeFromSuperview];
[self release];
}];
}
#end
and this is output
My ad.php
<?php
include("../includes/opencon.php");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Mobile Ad</title>
</head>
<body>
<?php
$setting = mysql_fetch_object(mysql_query("select * from my_settings where id=1"));
?>
<img src="http://url.com/media/<?=$setting->image?>" style="width:100%; height:auto;"/>
</body>
</html>
Please provide additional information, whether this happens when loading a local or remote image. I think for local images you could adjust your base url of the webview.
If you want to load local images, please provide the base URL of the App bundle:
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];
So instead of:
[web loadHTMLString: fileContents baseURL:[NSURL URLWithString:#"file://"]];
use the app bundle url:
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[web loadHTMLString: fileContents baseURL:baseURL];
For further debugging, you could set the webview's delegate to your view and check, what the webview's content looks like:
web.delegate = self;
To now use the delegate implement the following:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *html = [webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.outerHTML"];
NSLog(#"%#",html);
}
Alternatively, go to Safari->Develop->iPhone Simulator/iOS Device->Webview
And take a look at the source code in the debug console of safari.
Related
I have this file that I'm trying to reload but when I reload it I get the screen that is supposed to show up and then a blank screen until I hit reload again. I'm not sure why I'm getting this blank screen. Also, I do not get anything from
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {}
nor
-(void)didReceiveMemoryWarning
Here's my viewController.m file I have the index.html file in the same directory as it does load once but I'm not sure if webkit is crashing or where
#import "ViewController.h"
#import <WebKit/WebKit.h>
#import <JavaScriptCore/JavaScriptCore.h>
#interface ViewController ()
#end
#implementation ViewController
NSString *localURL;
NSURLRequest *urlRequest;
- (void)viewDidLoad {
[super viewDidLoad];
JSContext *ctx = [[JSContext alloc] init];
ctx[#"console"][#"log"] = ^(NSString *message) {
NSLog(#"Javascript log: %#", message);
};
// Do any additional setup after loading the view, typically from a nib.
// [UIView setAnimationsEnabled:NO];
//_webView = [[WKWebView alloc] initWithFrame:self.view.frame];
// _webView.navigationDelegate = self.webView ;
// _webView.UIDelegate = self;
//[self.view addSubview:_webView ];
_webView= [[WKWebView alloc] initWithFrame:CGRectMake(0, 100, 500, 500)];
localURL = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
urlRequest = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:localURL]];
[_webView loadRequest:urlRequest];
[self.view addSubview:_webView];
//button
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:#selector(reload) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Reload" forState:UIControlStateNormal];
button.frame = CGRectMake(10.0, 20.0, 100.0, 50.0);
button.backgroundColor = UIColor.blackColor;
[self.view addSubview:button];
}
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
// Reload current page, since we have crashed the WebContent process
// (most likely due to memory pressure)
NSLog(#"most likely due to memory pressure reloaded");
[webView reload];
}
-(void)reload{
NSLog(#"reloading now");
[self.webView loadRequest:urlRequest];
//[self.webView stopLoading];
// [self loadView];
//[_webView loadRequest:urlRequest];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
NSLog(#"memory issue");
}
//- (IBAction)rButton:(UIButton *)sender {
// NSLog(#"Well we didnt crash");
// [self.webView reload];
//}
#end
If the problem is due to a termination of the web the delegate function webViewWebContentProcessDidTerminate will be called.
In your case it looks that you didn't set the viewController as the navigationDelegate of the webview:
webview.navigationDelegate = self
This is about a web browser.
I have a custom Class that handles the webpages.
SNBrowserView
SNBrowserViewPage
SNBrowserViewPages have two objects.
WKWebView
UIImageView // Snapshot of the WKWebView
A function either sustains or recovers a page for memory management.
(Testing) Whenever a page is selected I call a recovery function.
Selection:
- (void)browserView:(SNBrowserView *)browserView didSelectPage:(SNBrowserViewPage *)page
{
if (page.sustained) {
[page recoverAnimated:NO];
}
}
Sustain:
- (void)sustain
{
_sustained = YES;
if (_webView) {
_webView = nil;
[_webView removeFromSuperview];
}
_snapshotView = [[UIImageView alloc] init];
_snapshotView.frame = CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height);
_snapshotView.image = _snapshot;
[self addSubview:_snapshotView];
}
Recover:
- (void)recoverAnimated:(BOOL)animated
{
_sustained = NO;
_webView = [[WKWebView alloc] init];
_webView.frame = CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height);
_webView.navigationDelegate = self;
_webView.UIDelegate = self;
[self addSubview:_webView];
[self sendSubviewToBack:_webView];
[self loadURL:_initialURL]; // Start loading as early as possible.
if (animated) {
[UIView animateWithDuration:0.3
animations:^{
_snapshotView.alpha = 0.0;
}
completion:^(BOOL finished){
_snapshotView = nil;
[_snapshotView removeFromSuperview];
}];
}
else {
_snapshotView = nil;
[_snapshotView removeFromSuperview];
}
}
When I try to recover a page the snapshotView is not set to nil nor is it removed from the superview.
How is that even possible?
Even this won't work:
- (void)recoverAnimated:(BOOL)animated
{
_snapshotView = nil;
[_snapshotView removeFromSuperview];
}
The snapshotView is a subview, removeFromSuperview should always work, why is there MORE to it?
I suggest you try replace all of your
_view = nil;
[_view removeFromSuperview];
with
[_view removeFromSuperview];
_view = nil;
because what you are doing is setting the _view to nil and then removing nil from superview.
1) I declared UIWebView as a property with strong attribute (strong) called webView;
2) In viewDidLoad method I am checking if my web constant exists or not. Based on that I will create with implicit constant of my webView property called _webView;
3) Then [[UIWebView alloc] initWithFrame:] give to my _webView;
4) Finally sometimes it crashes on iOS 8 or iOS 9 or iOS7 platform with the picture i post here from Fabric CrashReport;
- (void)viewDidLoad {
[super viewDidLoad];
[self setBaseNaviBarInfo];
if (_webInfoDictionary.count > 0) {
NSString *titile = [_webInfoDictionary objectForKey:#"activityName"];
[self setNaviItemText:titile];
}
[self createViews];
CLS_LOG(#"init create wb view ......");
NSString* url = [_webInfoDictionary objectForKey:#"activityLink"];
[self loadWebViewWithURLString:url];
}
-(void)createViews{
if (!_webView) {
//Crash Now
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, STATUS_NAVI_STATUS_HEIGHT, IPHONE_WIDTH, IPHONE_HEIGHT - STATUS_NAVI_STATUS_HEIGHT)];
_webView.delegate = self;
_webView.scalesPageToFit = NO;
_webView.dataDetectorTypes = UIDataDetectorTypeNone;
[self.view addSubview:_webView];
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithFrame : CGRectMake(0.0f, 0.0f, 32.0f, 32.0f)] ;
[_activityIndicatorView setCenter: self.view.center] ;
[_activityIndicatorView setActivityIndicatorViewStyle: UIActivityIndicatorViewStyleGray] ;
[self.view addSubview : _activityIndicatorView];
}
}
Crash Reference
I want the progressView working while my URL is loading. What should I do for that?
here's my .m code:
-(void)openURL{
UIWebView *webView = [[UIWebView alloc] init];
[webView setFrame:CGRectMake(0, 0, 320, 460)];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://google.com"]]];
[[self view] addSubview:webView];
}
- (IBAction)goto:(id)sender {
[self openURL];
}
Implement UIWebViewDelegate, specifically:
-(void)openURL{
UIWebView *webView = [[UIWebView alloc] init];
webView.delegate = self;
// ... rest of method as above ...
}
- webViewDidStartLoad:(UIWebView *)webView {
// Start progress.
}
- webViewDidFinishLoad:(UIWebView *)webView {
// Stop progress.
}
You could do something like this
[progressView startAnimating];
dispatch_async(dispatch_get_main_queue(), ^{
[webView loadRequest:yourRequest];
[progressView stopAnimating];
[progressView removeFromSuperView];
}
This will start the progress view before the operation begins, and will stop and remove it when it finishes.
I have a custom class like this:
#interface formParser : NSObject <UITextFieldDelegate> {
....
and in the .m I create a UITextField element like this:
UITextField *ui = [[UITextField alloc] initWithFrame:CGRectMake(left, top, width, height)];
[ui setDelegate:self];
[ui setPlaceholder:[dict_elementInfo objectForKey:#"placeholder"]];
[ui setBorderStyle:UITextBorderStyleLine];
[view addSubview:ui];
and
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
NSLog(#"should begin");
return NO;
}
My problem is that the shouldbegin is never called. When I try this technique on a "normal" UIViewController class it works perfectly, but doing this in my custom object it it never called.. Can anyone figure out why?
My custom class is called as follows:
formParser *fParse = [[formParser alloc] init];
UIView *view_formBackground = [fParse viewOfPlist:#"form" initSize:CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height)];
view_formBackground.backgroundColor = [UIColor whiteColor];
//add views to main view
[scrollView addSubview:view_formBackground];
[self.view addSubview:scrollView];
Also, in formparser.m the viewofplist is as follows:
-(UIView *)viewOfPlist:(NSString *)filename initSize:(CGRect)size
{
ypos_element_left = 40; ypos_element_right = 40;
view = [[UIView alloc] initWithFrame:size];
//load plist
NSString *path = [[NSBundle mainBundle] pathForResource:filename ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
rootArray = [dict objectForKey:#"form"];
//loop door alle UI entries in de dict.
for (NSDictionary *dict_UIElement in rootArray)
{
NSString *UIType = [dict_UIElement objectForKey:#"type"];
if ([UIType isEqualToString:#"ui_empty"]) [self handle_uiempty:dict_UIElement];
if ([UIType isEqualToString:#"ui_multiselect"]) [self handle_uimultiselect:dict_UIElement];
if ([UIType isEqualToString:#"ui_label"]) [self handle_uilabel:dict_UIElement];
if ([UIType isEqualToString:#"ui_textfield"]) [self handle_uitextfield:dict_UIElement];
if ([UIType isEqualToString:#"ui_choicefield"]) [self handle_uichoicefield:dict_UIElement];
if ([UIType isEqualToString:#"ui_calendar"]) [self handle_uicalendar:dict_UIElement];
}
return (view);
}
Thanks for answering!
Is one of your allocations falling out of scope and being cleaned up by ARC?
Helpful link on how the responder chain works..
http://developer.apple.com/library/ios/#documentation/general/conceptual/Devpedia-CocoaApp/Responder.html