UIWebView not resizing - objective-c

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

Related

Where to set the size of a view controller presented in a popover?

Based on Apple's sample code, my app is presenting a view controller in a popover, which is trigged by a bar button:
- (IBAction)configChartTapped:(id)sender {
GrowthChartConfigOneViewController *panelViewController = [[GrowthChartConfigOneViewController alloc]init];
UIPopoverController *popover = [[UIPopoverController alloc]initWithContentViewController:panelViewController];
popover.delegate = self;
// Store the popover in a custom property for later use.
self.popover = popover;
[self.popover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
However, I did not find a way to set the size of the popover.
Question: Where and how should I set the size of the popover and its view controller? Can I set the size directly in XCode to have the view correctly sized in storyboard?
You can also set it within the popover class itself. This way if you allow the popover to be called from multiple places, you can just set the size once.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
self.view.backgroundColor = [UIColor redColor];
self.contentSizeForViewInPopover = CGSizeMake(320.0, 216.0);
}
return self;
}
Just give popovercontentsize and make sure that view should fit in popover size as defined below:
popover = [[UIPopoverController alloc] initWithContentViewController: panelViewController];
popover.popoverContentSize = CGSizeMake(550, 700);
Good answer above but I just wanted to update it for storyboard due to my slightly different needs. If you're instantiating using storyboard identifier like this:
CBItemViewController *addNewPayee = [self.storyboard instantiateViewControllerWithIdentifier:#"cbItemPopover"];
then you can set the custom size inside the popover's code like this:
- (id)initWithCoder:(NSCoder *)decoder {
if(self = [super initWithCoder:decoder]) {
self.preferredContentSize = CGSizeMake(630, 340);
}
return self;
}

Generic "help" view which is accessible from all views in uinavigationView

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).

How do I get NSTextFinder to show up

I have a mac cocoa app with a webview that contains some text. I would like to search through that text using the default find bar provided by NSTextFinder. As easy as this may seem reading through the NSTextFinder class reference, I cannot get the find bar to show up. What am I missing?
As a sidenote:
- Yes, I tried setting findBarContainer to a different view, same thing. I reverted back to the scroll view to eliminate complexity in debugging
- performTextFinderAction is called to perform the find operation
**App Delegate:**
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
self.textFinderController = [[NSTextFinder alloc] init];
self.webView = [[STEWebView alloc] initWithFrame:CGRectMake(0, 0, self.window.frame.size.width, 200)];
[[self.window contentView] addSubview:self.webView];
[self.textFinderController setClient:self.webView];
[self.textFinderController setFindBarContainer:self.webView.enclosingScrollView];
[[self.webView mainFrame] loadHTMLString:#"sample string" baseURL:NULL];
}
- (IBAction)performTextFinderAction:(id)sender {
[self.textFinderController performAction:[sender tag]];
}
**STEWebView**
#interface STEWebView : WebView <NSTextFinderClient>
#end
#implementation STEWebView
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
}
- (NSUInteger) stringLength {
return [[self stringByEvaluatingJavaScriptFromString:#"document.documentElement.textContent"] length];
}
- (NSString *)string {
return [self stringByEvaluatingJavaScriptFromString:#"document.documentElement.textContent"];
}
In my tests, WebView.enclosingScrollView was null.
// [self.textFinderController setFindBarContainer:self.webView.enclosingScrollView];
NSLog(#"%#", self.webView.enclosingScrollView);
Using the following category on NSView, it is possible to find the nested subview that extends NSScrollView, and set that as the container, allowing the NSTextFinder to display beautifully within a WebView
#interface NSView (ScrollView)
- (NSScrollView *) scrollView;
#end
#implementation NSView (ScrollView)
- (NSScrollView *) scrollView {
if ([self isKindOfClass:[NSScrollView class]]) {
return (NSScrollView *)self;
}
if ([self.subviews count] == 0) {
return nil;
}
for (NSView *subview in self.subviews) {
NSView *scrollView = [subview scrollView];
if (scrollView != nil) {
return (NSScrollView *)scrollView;
}
}
return nil;
}
#end
And in your applicationDidFinishLaunching:aNotification:
[self.textFinderController setFindBarContainer:[self scrollView]];
To get the Find Bar to appear (as opposed to the default Find Panel), you simply have to use the setUsesFindBar: method.
In your case, you'll want to do (in your applicationDidFinishLaunching:aNotification method):
[textFinderController setUsesFindBar:YES];
//Optionally, incremental searching is a nice feature
[textFinderController setIncrementalSearchingEnabled:YES];
Finally got this to show up.
First set your NSTextFinder instances' client to a class implementing the <NSTextFinderClient> protocol:
self.textFinder.client = self.textFinderController;
Next, make sure your NSTextFinder has a findBarContainer set to the webView category described by Michael Robinson, or get the scrollview within the webView yourself:
self.textFinder.findBarContainer = [self.webView scrollView];
Set the find bar position above the content (or wherever you wish):
[self.webView scrollView].findBarPosition = NSScrollViewFindBarPositionAboveContent;
Finally, tell it to show up:
[self.textFinder performAction:NSTextFinderActionShowFindInterface];
It should show up in your webView:
Also, not sure if it makes a difference, but I have the NSTextFinder in the XIB, with a referencing outlet:
#property (strong) IBOutlet NSTextFinder *textFinder;
You may also be able to get it by simply initing it like normal: self.textFinder = [[NSTextFinder alloc] init];

Different transparencies in Cocoa?

I have overloaded NSWindow and have created a custom window of my own (Borderless and transparency of 0.3 alphaValue). I am going to be drawing images in this window. Is there any way I can get the images that will be drawn in the window opaque? I want the window to remain transparent but want the images to be opaque. How would I do this?
Mac OS X Snow Leopard
Xcode 3.2.6
#ughoavgfhw is on the right track, but it's actually much easier. You just need to set opaque to NO and set backgroundColor to semi-transparent.
#implementation MYWindow
- (void)setup
{
[self setStyleMask:NSBorderlessWindowMask];
[self setOpaque:NO];
[self setBackgroundColor:[NSColor colorWithCalibratedWhite:1.0 alpha:0.3]];
}
// We override init and awakeFromNib so this works with or without a nib file
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag
{
self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag];
if (self)
{
[self setup];
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self setup];
}
#end
There's a potential problem with this approach.
Requesting "[self setStyleMask:NSBorderlessWindowMask];" (with any of the possible StyleMask values) will cause the loss of keystroke events to that window on subsequent presentations of the window as a sheet. I reported a bug to Apple today on this point.
Leave the alphaValue property to 1, and set the opaque property to NO. Then, replace the default contentView with one which fills itself with a color whose alpha component is 0.3 in its drawRect: method. When you change the alphaValue property, it changes how everything drawn in the window is displayed. When you make it non-opaque, it simply doesn't draw a black background beneath the content view, so if the content view is transparent, the window will be too, but anything drawn on top of that will not be affected.
Here's an example which uses a white background with a 0.3 alpha component. Note that I overrode the setContentView: method. This is so that I can copy any views from the passed view into the transparent content view, and is especially necessary if you load the window from a nib, since the nib loading will change the content view when it is loaded. (You could change the content view's class in IB instead.)
#interface MyWindow_ContentView : NSView
#end
#implementation MyWindow
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
if(self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag]) {
[super setOpaque:NO];
[super setContentView:[[[MyWindow_ContentView alloc] init] autorelease]];
}
return self;
}
- (void)setOpaque:(BOOL)ignored {}
- (void)setContentView:(NSView *)newView {
NSArray *views = [[self.contentView subviews] copy];
[views makeObjectsPerformSelector:#selector(removeFromSuperview)];
views = [[newView subviews] copy];
[views makeObjectsPerformSelector:#selector(removeFromSuperview)];
for(NSView *view in views) [self.contentView addSubview:view];
[views release];
}
#end
#implementation MyWindow_ContentView
- (void)drawRect:(NSRect)rect {
[[NSColor colorWithCalibratedWhite:1 alpha:0.3] set];
NSRectFill(rect);
}
#end

UITableView Overlay when section index touched

I have a very custom table view that actually serves as a content view, but table view was the obvious choice. I have a section index that i use to scroll the TableView - but there are no sections (well, one is there obviously). For the purpose of the user's orientation, I'd like to fade a view over the table view that is semi-transparent and shows a text in there. It should look like the overlay with the letters when scrolling the new iPod nano's section index. I don't know where i should put the code - because my view has to disappear sometime again too, and I don't really wanna use notifications. I'd init the view inside the tableview: sectionForSectionIndexTitle method. Thanks in advance.
Create a property in your .h file
#property (nonatomic, retain) UILabel *overlayLabel;
And add the following code to your .m file
- (void)viewDidLoad {
[super viewDidLoad];
self.overlayLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0.0f,
0.0f,
self.tableView.frame.size.width,
self.tableView.frame.size.height)] autorelease];
overlayLabel.backgroundColor = [UIColor clearColor];
overlayLabel.alpha = .5f;
overlayLabel.textAlignment = UITextAlignmentCenter;
overlayLabel.text = #"Some text";
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView addSubview:overlayLabel];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[overlayLabel removeFromSuperview];
}