I am using the UIWebView on iPad, which I initialize by the code below. The problem is that the view is never displayed on the top of the page just under the Status bar, but there is another 44px space (filled with black color) - for Navigation Bar, which I do not want to display. Any hints how I can make the UIWebView be displayed without the 44px space?
Thanks a lot,
BR
STeN
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect rectApp = [[UIScreen mainScreen] applicationFrame];
self.webView = [[[UIWebView alloc] initWithFrame:rectApp] autorelease];
self.webView.backgroundColor = [UIColor whiteColor];
self.webView.scalesPageToFit = YES;
self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
self.webView.delegate = self;
[self.view addSubview: self.webView];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.test.com/shop/index.php"]]];
}
The problem is that the coordinate system of the view you're adding it to isn't the coordinate system of the window; the view has already been adjusted for the status bar.
Change it thus:
CGRect rectApp = [[UIScreen mainScreen] applicationFrame];
rectApp.origin = CGPointZero;
Or better yet, use self.view.bounds, since self.view presumably refers to a view that fills the application's window anyway.
I like Tony's answer. When I ran into this problem I used the generic view.frame = self.view.bounds, in your code this would be written:
self.webView.frame = self.view.bounds;
Related
I'm implementing some sort of loading screen consisting of a black coloured uiview with a spinner at it's center.
When the tableview has been scrolled down and the loading goes, the loading screen is at the top and if the tableview has been scrolled to the bottom, the loading screen disappears.
Function:
UIView *blackScreen = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
blackScreen.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
blackScreen.tag = LOADING_SCREEN_TAG;
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.center = CGPointMake(CGRectGetWidth(self.view.bounds)/2,
CGRectGetHeight(self.view.bounds)/2.3);
spinner.tag = SPINNER_TAG;
[spinner startAnimating];
[self.view addSubview:blackScreen];
[self.view addSubview:spinner];
[self.view setUserInteractionEnabled:NO];
You need to add contentOffset, I would like to refer you to this page which explains the use of it.
Here's the solution anyway, this is assuming that the variable name of your tableview is tableView and is set as a property of the class:
CGRect loadingScreenFrame = CGRectMake([[UIScreen mainScreen] bounds].origin.x + self.tableView.contentOffset.x,
[[UIScreen mainScreen] bounds].origin.y + self.tableView.contentOffset.y,
[[UIScreen mainScreen] bounds].size.width,
[[UIScreen mainScreen] bounds].size.height);
UIView *blackScreen = [[UIView alloc] initWithFrame:loadingScreenFrame];
blackScreen.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
blackScreen.tag = LOADING_SCREEN_TAG;
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.center = CGPointMake((CGRectGetWidth(self.view.bounds)/2) + self.tableView.contentOffset.x,
(CGRectGetHeight(self.view.bounds)/2.3) + self.tableView.contentOffset.y);
spinner.tag = SPINNER_TAG;
[spinner startAnimating];
[self.view addSubview:blackScreen];
[self.view addSubview:spinner];
[self.view setUserInteractionEnabled:NO];
A solution would be to not add the spinning view to the tableview but rather to its superview. It seems like you are probably using a UITableViewController which would mean that you would need to restructure your code to use a UIViewController to make this work. Adding both the UITableView and the spinner view to the view of the UIViewController would also achieve what you are looking for without having to set the center based on the content offset.
I am implementing UIViewcontroller containment. In the example below I set the frame size of the childcontrollers in the rootcontroller. The child view appears as the size I have set, however when I check on its bounds within container1 it reports a different size to the size I set.
Rootcontroller (container)
- (void)viewDidLoad
{
[super viewDidLoad];
self.containA = [[Container1 alloc]init];
self.containB = [[Container2 alloc]init];
self.containA.view.frame = CGRectMake(50, 50,50, 50);
self.containB.view.frame = CGRectMake(50, 50, 300, 300);
[self addChildViewController:self.containA];
[self addChildViewController:self.containB];
[self.view addSubview:self.containA.view];
Container1
-(void)viewDidLoad {
[super viewDidLoad];
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
//[self.view addSubview:view];
self.view = view;
self.view.backgroundColor = [UIColor redColor];
[view release];
NSLog(#"view dims %f %f",self.view.bounds.size.width,self.view.bounds.size.height);
}
Console output from container 1
view dims 768.000000 1004.000000
I thought the issue was related to setting the view frame to UIScreen main screen]applicationFrame .So I removed all of this code so the uiview is created automatically. The issue still remains..
View frames are not actually useable in viewDidLoad; you should move all of your geometry-manipulating code into viewWillAppear. The system will clobber any changes you set in viewDidLoad between there and when it's about tom come on screen.
So I've read this post
But it doesn't seem to deal with the issue of making the background NOT tint to a semi-transparent. I want the content behind the menu with buttons to be clearly visible. Is this even possible?
This is what I have currently
WPSActionSheet *actionSheet = [[WPSActionSheet alloc] initWithCompletion:completion];
[actionSheet setTitle:#""];
[actionSheet addButtonWithTitle:#"Take Photo"];
[actionSheet addButtonWithTitle:#"Choose from Library"];
[actionSheet addButtonWithTitle:#"Skip This Step"];
[actionSheet setCancelButtonIndex:2];
[actionSheet showInView:[self view]];
which shows this
UIActionSheet will always show the "tinted background". There is no way around this. You can however create your own version of the UIActionSheet using a UIView.
Just set the alpha and opaque property of UIActionSheet with delegate method -
(void)willPresentActionSheet:(UIActionSheet *)actionSheet
and it will be visible as you want.
If you want to make background of UIActionSheet transparent you can subclass it and change layoutSubviews
- (void)layoutSubviews
{
[super layoutSubviews];
UIImage* image;
CGSize size = self.frame.size;
UIGraphicsBeginImageContext(size);
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[[self layer] setContents:(id)image.CGImage];
}
To add some custom background just add following code to layoutSubviews:
CGRect frame = self.frame;
frame.origin = CGPointZero;
UIImageView* bg = [[UIImageView alloc] initWithFrame:frame];
bg.image = [UIImage imageNamed#"YOUR/IMAGE/NAME"];
[self addSubview:bg];
[self sendSubviewToBack:bg];
Also you can do all those actions in delegate method
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
simply replacing self to actionSheet.
I had the same problem and found a workaround. The UIActionSheet's superview contains a UIView that is used for the tinting. So you can remove the tinting by setting the opacity of this view's layer to 0.
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet {
NSArray *subviews = actionSheet.superview.subviews;
UIView *tintView = [subviews objectAtIndex:0];
[tintView.layer setOpacity:0.0];
}
It's pretty embarrassing asking this because I've been building apps for a while now. In the past I've always used Interface Builder to set up my views etc.
Here is my loadView:
- (void)loadView {
UIView *splashView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
splashView.backgroundColor = [UIColor clearColor];
UIImageView *splashImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[[NSBundle mainBundle]pathForResource:#"splash" ofType:#"jpg"]]];
splashImage.frame = [splashView bounds];
[splashView addSubview:splashImage];
self.view = splashView;
}
For some reason the imageView isn't appearing. No errors, but just no appearance. The UIView is added, but the UIImageView isn't.
Like I said, I've traditionally done this with IB so I'm not so familiar with the programatic method.
Any help appreciated.
Add splashView to self.view:
self.view = splashView;
or add your splashImage into self.view. In this case you don't need the UIView - splashView:
UIImageView *splashImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[[NSBundle mainBundle]pathForResource:#"splash" ofType:#"jpg"]]];
splashImage.frame = [splashView bounds];
[self.view addSubview:splashImage];
Try not creating a new view called splash view and just add the image view to your self.view.
I am trying to duplicate the UISearchBar animation seen in mobile Safari. Instead of only moving the left margin, the UISearchBar Expands off the screen and then "jumps" into the proper location. The downsizing is similarly uneven. How can I make this animation even like the UISearchBar in mobile safari?
searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0,0,175,44)] autorelease];
searchBar.delegate = self;
searchBar.showsCancelButton = YES;
searchBar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth;
UIBarButtonItem *customBarItemRight = [[[UIBarButtonItem alloc] initWithCustomView:searchBar] autorelease];
tabBarController.navigationItem.rightBarButtonItem = customBarItemRight;
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
searchDisplayController.searchResultsTableView.hidden = NO;
[UIView animateWithDuration:.3
animations:^ {
CGRect newBounds = searchBar.bounds;
newBounds.size.width = 350;
searchBar.bounds = newBounds;
}];
[searchDisplayController setActive:YES animated:YES];
}
You should not use UISearchDisplayController for this, you need to implement animation for your custom view controller.