In laying out CALayer objects in the main view of a viewController I am seeing a discrepancy between IOS 43. and 5.1
I am running in landscape mode. I want a CALayer object 40 pts wide, showing at the top left -- butted up against the nav bar and the full height of the screen (less the nav bar). Status bar is disabled. I calculate the height of the layer as the height of the view less the height of the nav bar.
In viewDidLoad of my viewController I have the following code....
[[UIApplication sharedApplication] setStatusBarHidden:YES];
CGRect viewFrame = self.view.frame;
float navBarHeight = self.navigationController.navigationBar.frame.size.height;
CGRect f = CGRectMake( 0, navBarHeight, 40, viewFrame.size.height - navBarHeight);
leftLayer = [[CALayer alloc] init];
leftLayer.frame = f;
leftLayer.backgroundColor = [UIColor greenColor].CGColor; // for debug
[self.view.layer addSublayer:leftLayer];
When I run this on 5.1 viewFrame = (0, 0, 480, 288) and navBarHeight = 32. When I run this on 4.3 viewFrame = (0, 0, 480, 320) and navBarHeight = 32. I've tried the same comparison in portrait mode and there is no discrepancy between OS versions.
navBarHeight also seems wrong -- because my green CALayer object has about 12 pts of white space between it and the nav bar. What am I doing wrong?
I have better luck with using the viewWillAppear method to adjust frames because the view has been sized for the orientation by then. Do you have the same issue in that method?
Related
I am trying to convert scroll view coordinates to window coordinates. However the resulting frame seems to be shifted by status bar height, what's confusing is that the height remains the same which is not right.
CGRect visibleBounds = CGRectMake(0, 0, CGRectGetWidth(self.scrollView.frame), CGRectGetHeight(self.scrollView.frame));
CGRect scrollViewFrame = [self.scrollView convertRect:visibleBounds toView:nil];
lldb log:
Printing description of visibleBounds: (CGRect) visibleBounds =
(origin = (x = 0, y = 0), size = (width = 320, height = 568))
Printing description of scrollViewFrame: (CGRect) scrollViewFrame = (origin =
(x = 0, y = 20), size = (width = 320, height = 568))
Turns out scroll view bounds can be used to calculate the frame for scroll view in window coordinates, regardless the fact that I see negative bounds, produced frame will be correct anyway.
[self.scrollView convertRect:self.scrollView.bounds toView:nil];
I have a TableViewController with a UIActivityIndicatorView as a subview while the content loads and it works like it should. The only problem is that I can't get the activity indicator centered on the screen.
CGFloat width = CGRectGetWidth(self.view.bounds);
CGFloat height = CGRectGetHeight(self.view.bounds);
loadingIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(width / 2, height / 2, 125, 125)];
loadingIndicator.center = CGPointMake(width / 2, height / 2);
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
loadingIndicator.hidesWhenStopped = YES;
[self.tableView addSubview:loadingIndicator];
[loadingIndicator startAnimating];
Also worth noting, the large indicator seems to be shifted 3 pix left and up. (swift, iOS 9.2.1)
Maybe its because your view is of wrong size in xib(say, its for iPhone 5 in xib and you are running it on iPhone 6 ).
So, your height and width calculation is wrong.
Instead, try using
CGFloat width = CGRectGetWidth(UIScreen.mainScreen.bounds);
CGFloat height = CGRectGetHeight(UIScreen.mainScreen.bounds);
Hope it helps :)
Try the Code :
CGFloat width = CGRectGetWidth(self.tableView.bounds);
CGFloat height = CGRectGetHeight(self.tableView.bounds);
UIActivityIndicatorView *loadingIndicator;
loadingIndicator = [[UIActivityIndicatorView alloc]init];
loadingIndicator.center = CGPointMake(width / 2, height / 2);
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
loadingIndicator.hidesWhenStopped = YES;
[self.tableView addSubview:loadingIndicator];
[loadingIndicator startAnimating];
Try
[loadingIndicator setCenter:[self.tableView center]];
try by change this line loadingIndicator.center = CGPointMake(width / 2, height / 2); to loadingIndicator.center = self.view.center; and add the subviewloadingIndicator to self.view
Your code is perfect, but I think you set frame on basic of self.view and added that indicator on tableview.
so add that indicator on self.view.
If your problem is that the position is not correct horizontally, it may be that view's bounds is still the freedom width from your storyboard.
Try to put your code in viewDidLayoutSubviews. To avoid repeated adding to the view, set the activityObject as a property of this class.
Tejvansh Singh Chhabra's answer is good when you want to center in the screen. Just when generally if you want to position view based on view's frame or bounds, put code after viewDidLayoutSubviews stage, or add constraints to the view.
I had an application in which I want to hide my navigation bar when scrolling upwards in a UITableView. I am doing like this
- (void)scrollViewDidScroll:(UIScrollView *)sender {
//Initializing the views and the new frame sizes.
UINavigationBar *navbar = self.navigationController.navigationBar;
UIView *tableView = self.view;
CGRect navBarFrame = self.navigationController.navigationBar.frame;
CGRect tableFrame = self.view.frame;
//changing the origin.y based on the current scroll view.
//Adding +20 for the Status Bar since the offset is tied into that.
navBarFrame.origin.y = MIN(0, (sender.contentOffset.y * -1)) +20;
navbar.frame = navBarFrame;
tableFrame.origin.y = MIN(0,MAX(-44,(sender.contentOffset.y * -1)));
tableView.frame = tableFrame;
}
But the problem is that it is moving completely upwards in iOS 7. I need it to be stopped under the status bar and the status bar is shown there.
https://github.com/ninjinkun/NJKScrollFullScreen ...Hope this will help any other
Playing around with iOS6 today, and I got stuck on checking view frame size under various orientations, which I thought I understood in iOS5. (I understand that auto-layout solves the basic problem in many cases, but still I feel I may need this check for various reasons?).
With auto-layout off, checking the view dimensions returns the right dimension size, but not the correct edge. That is to say in portrait on the iPhone the .width property = 320 and in landscape the .width property = 300, whereas I would expect 300 to be the value of the height dimension.
This is kind of weird to me as the self.view does scale properly to the window, but another view set to the frame of the self.view does not. This would be easy to fix by checking the orientation then getting the right numbers, I guess, but am I missing something obvious, or some new rule in iOS6?
//always gives aprox 300 for width despite device orientation
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
screenRect = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
screenRect = self.view.window.frame;
NSLog(#"screen rect size = %f x %f", screenRect.size.width, screenRect.size.height);
[imageView setFrame:screenRect];
}
//a button to check orientation. always gives aprox 300 for width despite device orientation
- (IBAction)checkScreenSize:(id)sender {
screenRect = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
NSLog(#"screen rect size = %f x %f", screenRect.size.width, screenRect.size.height);
screenRect = [[UIScreen mainScreen]applicationFrame];
NSLog(#"screen rect size = %f x %f", screenRect.size.width, screenRect.size.height);
}
On iPad following is offscreen when in portrait, why this even when starting up in portrait?
- (void)viewDidLoad
{
[super viewDidLoad];
UIView* imageView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
blue.backgroundColor = [UIColor blueColor];
[[self view] addSubview:imageView];
I have been told that the root view's frame is always the same in portrait and landscape:
- portrait frame orign(x i representing the orign of an UIView)
x0
00
00
Landscape frame orign:
000
x00
But why is CGRectMake(0,0 .. not up in the right corner in portrait?
Thanks in advance
The bounds and the frame can change when you rotate the device. Let's take a Single View Application template as an example, add orientation support and run it on the iPhone. In portrait:
bounds = (0, 0, 320, 460) // 460 compensates for 20p status bar
frame = (0, 20, 320, 460) // status bar adjustment
x0
00
00
In landscape:
bounds = (0, 0, 480, 300) // now 20p is taken from "height"
frame = (20, 0, 300, 480) // status bar adjustment
x00
000
Origin is always top-left corner, regardless of orientation.