I'm setting up a ViewController that will hold a couple of UIViews, including UIWebView
I'm creating and adding those Views programmatically in the viewDidLoad method.
Is this approach satisfactory? or am I doing something too expensive for the hardware.
and how do I load new data into a WebView that was created in the ViewDidLoad method.
I have a properly of type UIWebView, then in the ViewDidLoad i do:
detailsView = [[UIWebView alloc] initWithFrame:CGRectMake(500, 0, 512, 768)];
and this does not seem to work:
- (void)loadDetailedContent:(NSString *)s
{
[detailsView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
[detailsView reload];
}
Waiting for your reply, thank you in advance
You can certainly create and add subviews in your viewController's viewDidLoad programmatically, but you'll have to remember to call addSubview if you want them to appear on the screen.
- (void)viewDidLoad
{
[super viewDidLoad];
detailsView = [[UIWebView alloc] initWithFrame:CGRectMake(500, 0, 512, 768)];
[self.view addSubview:detailsView];
}
As for your second question about loading data into your webview, there is no need to call reload immediately after calling loadRequest:.
- (void)loadDetailedContent:(NSString *)s
{
[detailsView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
}
Related
I've tried everything I can think of to get my UIWebView to fill the screen automatically on an Iphone 4, 5 and Ipads. I've used auto resizing masks, tried setting the frame programmatically based on the device and still noting has worked.
This is not a scaling problem with the HTML that gets loaded the scroll bars are actually not where they should be.
What am I doing wrong? I know it shouldn't be this difficult.
#interface webview ()
#end
#implementation webview
#synthesize weber;
#synthesize suppressesIncrementalRendering;
static NSString* titled;
static NSString* urlholder;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void)viewWillAppear:(BOOL)animated
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}
-(void)viewDidDisappear:(BOOL)animated
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.weber.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
self.title= titled;
NSString *fullURL = urlholder;
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[weber setSuppressesIncrementalRendering:YES];
[weber loadRequest:requestObj];
wasLoaded = NO;
alertWasShown = NO;
weber.delegate = self;
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
wasLoaded = YES; // Indicates that it finished loading.
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
-(void) setttl: (NSString*) titler
{
titled= titler;
}
-(void) setURL: (NSString*) url
{
urlholder= url;
}
Nowhere in your code do I see where you are setting the initial frame for the webview. The resizing masks determine how it resizes, but they do not determine the size of the view to start with.
It looks like you are using a xib, try setting the size of the webview to fit correctly in its superview. Then use InterfaceBuilder to set the resizing properties in the Size inspector.
Alternatively, you could set the size programmatically:
self.weber.frame = CGRectMake(0.0, 0.0, 200.0, 700.0);
Assuming the superview fills the screen you should assign the frame of the UIWebView as the bounds of its parent in viewDidLoad:
self.weber.frame = self.view.bounds;
If your UIWebView is being programmatically instantiated the code would look something like this:
-(void)viewDidLoad
{
[super viewDidLoad];
self.weber = [UIWebView new];
self.weber.frame = self.view.bounds;
[self.view addSubview:self.weber];
}
I just came across this question because I had a similar problem. What fixed it for me was setting the frame of my UIWebView in viewDidLayoutSubViews instead of in viewDidLoad. This was suggested by entonio in a comment on one of the other answers, but I'm putting it here as an answer so it's easier to find if someone else comes along.
It appears that storyboard overrides any code to resize UIWebView. If you're trying to load a dynamic html/css into a UIWebView and it won't resize on Orientation change: Try unchecking the "autolayout" setting.
Select .storyboard file
Go to identity qand type window (see link snapshot)
Uncheck "Use Auto Layout" in Interface Builder Document section.
Source: http://forums.macrumors.com/showthread.php?t=1705519
I tried to add TapforTap Ads to my iPhone app, the ad appear but I show this message in console "Unbalanced calls to begin/end appearance transitions for ." after any navigation of pages and then the app crash, the below code for calling TapForTap Ads. How I can solve this problem?
- (void)viewDidLoad
{
[super viewDidLoad];
CGFloat y = self.view.frame.size.height - 50.0;
TapForTapAdView *adView = [[TapForTapAdView alloc] initWithFrame: CGRectMake(0, y, 320, 50) delegate: self];
[self.view addSubview: adView];
[TapForTapAppWall prepare];
[TapForTapAppWall showWithRootViewController: self]; // or possibly self.navigationController
}
Thanks A lot
I don't know it for sure. But try this:
- (void) ShowTapAd {
CGFloat y = self.view.frame.size.height - 50.0;
TapForTapAdView *adView = [[TapForTapAdView alloc] initWithFrame: CGRectMake(0, y, 320, 50) delegate: self];
[self.view addSubview: adView];
[TapForTapAppWall prepare];
[TapForTapAppWall showWithRootViewController: self]; // or possibly self.navigationController
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelectorOnMainThread:#selector(showTapAd) withObject:nil waitUntilDone:NO];
}
The run time warning that you got appears when you hussle with two (or more) segue, Navigation Controller push or present modally types of processes. Meaning when you initiate one before the former was totally finished.
I am surprised that those things can happen when you call something within viewDidLoad. So you may find out that the root cause is not located within the code sniplet that you have shown. But if it is then this could do the trick.
What it does:
It just makes sure that your setup of the ad view is performed after viewDidLoad is properly finished. As viewDidLoad runs on the main tread as all UI related stuff does (or should do), the current appearance transistion should be finised by then.
Hope, this helps. Again, it is just a guess.
I'm trying to move a uiLabel down a drop if it's an iPhone 5 (4" display). But it's not working when the code is in viewDidLoad. If I call the code from clicking a uiButton, it works. Here's the code:
-(void) viewDidLoad {
if(CGSizeEqualToSize([[UIScreen mainScreen] preferredMode].size,CGSizeMake(640, 1136))) {
CGRect frame = [self.timeOnCurrentQuestion frame];
frame.origin.y += 40; // change the location
[self.timeOnCurrentQuestion setFrame:frame];
nslog(#"This DOES get logged");
}
}
Jonah, have you tried your code in viewWillAppear method? Possibly, it'll sort-out your issue.
Maybe that are something you need to beware of.
- (void)viewDidLoad
It is a method that when the controller juz created its view.
for example:
maybe in your init method, you call something like:
[self.view setBackground:[UIColor redColor]];
self.timeOnCurrentQuestion = [[UIView alloc] initWithFrame:kFrame];
In this case the work flow will be like this:
[self.view setBackground:[UIColor redColor]];
[self viewDidload];
self.timeOnCurrentQuestion = [[UIView alloc] initWithFrame:kFrame];
Th reason for this work flow is because the self.view is called, then its view is needed before the normal view cycle, so , in this case, self.timeOnCurrentQuestion is still nil in the viewDidload method.
I don't know if my practice is the best or not.
I always init the subView in the controller's init method.
and do the [self.view addSubview:_subview] (//or everything method call that require the self.view) in [self viewDidload];
viewDidAppear worked for me. The life cycle seems to be
LoadView()
viewDidLoad()
viewWillAppear()
viewDidAppear()
Assuming an application has many views pushed to a uinavigationViewController, each view is different in content.
since the elements in the app are complex, I would like to show a small help view for specific views or elements in a specific view.
Imagine a "?" button that when pressed on will pop a new view in the center of the screen, playing youtube help video, or just a textual HTML loaded from a remote server.
Question: what is the best strategy for doing such a thing?
where should I place this code (App Delegate?)
if so, how would I call it from other views (with URL Parameter)
-(void)showHelpView:(NSString *)theURLString{
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)];
//webView.delegate= self;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:theURLString]]];
[window addSubview:webView];
[window makeKeyAndVisible];
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
}
I'd prefer using pseudo-modal views. So that you create view every time, and add it on top of current window. I've used this approach for OAuth 2.0 authorisation popup in my last app.
Basically you create custom UIViewController subclass, provide custom initialisator, such as, for example:
// - (id) initWithURL: (URL*)url {
// ...
// self.url = url;
// ...
// return self;
PseudoModalViewController* pmvc = [[PseudoModalViewController alloc] initWithURL:#"http://www.google.com/"];
After you've created view you add it on top of current window:
UIWindow* window = [[UIApplication sharedApplication] keyWindow];
if(!window)
{
window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
}
[window addSubview:pmvc.view];
In, for example, viewDidLoad you load url obtained in initialisator:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}
You may even design UI in Interface Builer for that. As a last piece I'd recommend add to include full screen transparent background view to ensure that all views below are disabled.
Oh, almost forgot, you hide that view with just a simple [self.view removeFromSuperview]. Don't forget to provide correct memory management for that view (i.e. release it in time, etc).
I'm adding a button in the middle of my initWithNibName:bundle:, when i add the button view to self.view, the view goes to start to initialize before it add's the button. So the Code in viewDidLoad gets fires before the initWithNibName:bundle: is finished. There is code below the addSubview that is relied on in the viewDidLoad and causes it to crash/not work since the init code has not run.
I've had the same experience when I added the button code to the viewDidLoad method. There is a UITableView in the .xib and the table gets inited before the rest of the viewDidLoad gets run and caused the tableView to get bad Data.
What is the best practice for adding a view to a view when you are initing and loading the view? just put all the addSubViews before the Return?
Thanks!
Here is my initWithNibName:bundle:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nil];
[self setIoUIDebug:(IoUIDebugSelectorNames)];
if (IoUIDebug & IoUIDebugSelectorNames) {
NSLog(#"%# - %#", [self description], NSStringFromSelector(_cmd) );
}
CGRect frame = CGRectMake(20, 521, 500, 37);
saveButton = [UIButton newButtonWithTitle:NSLocalizedStringFromTable(#"Save Animation Label",#"ScreenEditor",#"Save Animation Label")
target:self
selector:#selector(saveButtonPressedAction:)
frame:frame
image:[UIImage imageNamed:#"BlueButtonSmall.png"]
imagePressed:[UIImage imageNamed:#"BlueButtonSmallPressed.png"]
darkTextColor:NO];
[self.view addSubview:saveButton]; // <- Right here I'll hit breakpoints in other parts of viewDidLoad and cellForRowAtIndexPath, before the lined below get executed.
[saveButton setEnabled: NO];
[saveButton setUserInteractionEnabled: NO];
newAnimation = nil;
selectedSysCDAnimation = nil;
selectedIoCDTag = nil;
animationSaved = NO;
return self;
}
You should add the subviews inside viewDidLoad this will mean that the views are added when the main view is loaded into memory. I would reserve your initWithNibName:bundle: call for custom initialization and not interacting with the UI as this what viewDidLoad is designed for.
In regards to your tableView, you should put a call to load the tables datasource inside of viewDidLoad. Once the datasource is loaded, you can simply call reloadData on the tableview to load the data into the tableview.
For Example:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:saveButton];
[self loadDataSource];
}
- (void)loadDataSource {
// load datasource here
[self.tableView reloadData];
}
Any access to the view property of the view controller will lazily initialize the view. This will trigger a call to viewDidLoad which will execute before the access to the view property returns in initWithNibName:. You should add the sub view in viewDidLoad or using interface builder.