0

I'm trying to display a custom view like an action sheet in a root view controller within a UINavigationController, but I always end up having the bottom obscured because I don't account for the UINavigationBar + status bar height.

For example the following code will have 64 points worth of bottom part of customView obscured:

CGFloat height = [UIScreen mainScreen].bounds.size.height;

[UIView animateWithDuration:0.5 animations:^{
    customView.center = CGPointMake(width / 2.0, height - customViewHeight / 2.0);
}];

I could just use setFrame instead of center but that is irrelevant because it will give me the same results more or less.

I know using constants like -64 pts is not desirable, so is there a away to convert points to the actual screen coordinates? What is the best practice?

Edit (Possibly an additional question)

I'm trying to have a view from outside the bottom of the screen slide in like an UIActionSheet, and every time I try to do this, I always run into the same problem.

I try to set the initial subview frame origin.y to the height of the screen, and have the subview animate to (screenHeight - subviewHeight), which is why I always run into my problem of having the bottom 64 CGPoints obscured.

What's the best way to do this kind of implementation? I've tried searching for sample code, but I've only seen codes using height like CGPoint height = 480.0 - subviewHeight;, which I heard is poor practice.

funct7
  • 3,407
  • 2
  • 27
  • 33

3 Answers3

1

One way to do this

@implementation UIView (XXScreenConversions)
- (CGPoint)xx_pointFromScreenPoint:(CGPoint)point {
    CGPoint inWindow = [self.window convertPoint:point fromWindow:nil];
    return [self.window convertPoint:inWindow toView:self];
}

- (CGPoint)xx_screenPointFromPoint:(CGPoint)point {
    CGPoint inWindow = [self.window convertPoint:point fromView:self];
    return [self.window convertPoint:inWindow toWindow:nil];
}
@end
Adlai Holler
  • 830
  • 7
  • 10
  • This helps! Thanks! But just for future reference, is this what I have to use all the time when I want to account for the offset for `origin.y` – funct7 Apr 29 '14 at 02:40
1

In addition to Adam's response, I don't think you should rely on the screen height in your calculations here either. Because it's likely the superview you are adding your subview too isn't actually full screen, so it's pushing the bottom off.

If you're slinging rects around, you're better off grabbing the view.bounds of the view you're adding it too and using that for your frame calculations.

If you're using auto layout (if not, learn it cause it's awesome), use the topLayoutGuide.

petehare
  • 1,874
  • 16
  • 14
  • I used view.bounds, but it gives the same result. I'll have to look into topLayoutGuide, but I'm not using auto layout. – funct7 Apr 29 '14 at 02:07
  • It's a little hacky, but you could inset the view.bounds rect with the topLayoutGuide.constant. That's essentially what auto layout does when insetting scrollViews. – petehare Apr 29 '14 at 05:57
0

You are confusing points and pixels. Point is a measure of typography that comes from the days of hot metal typesetting (and it can mean a number of physical measurements). A point in the CGPointMake sense is simply a location on the screen measured in pixels. What you need to be doing is to measure the height value more accurately.

You should have a look at this page in the Apple "iOS 7 UI Transition Guide" to get a handle on how to use helper views like topLayoutGuide in calculating the height of the screen correctly. Very likely you're going to find topLayoutGuide takes care of the 64 pixels perfectly, it always has in my experience.

Adam Eberbach
  • 12,309
  • 6
  • 62
  • 114
  • Yes, I mean point as in CGPoint. I thought using pixels causes more confusion because of retina and non-retina display. – funct7 Apr 29 '14 at 02:04
  • Mostly you can forget about whether something is a retina display or not! To the developer, a device's native coordinate system is the non-retina dimension and retina just works. You can look at the scale property but often this is just a path to confusion. – Adam Eberbach Apr 29 '14 at 02:09
  • Well, then what's the non-confusing, widely-accepted terminology when you say the navigation bar + status bar height is "64 CGPoints"? (Not too relevant to the question per se, but for future reference) – funct7 Apr 29 '14 at 02:17
  • CGPoint is a struct containing both x and y values, so it isn't right to talk about 64 of them unless you mean 64 locations in 2D space. When you want to talk about the height of the nav bar + status bar it is just pixels. – Adam Eberbach Apr 29 '14 at 02:34
  • Okay, my bad for saying CGPoints. I meant to say floating-point values. I know you know much more about programming than I do, but I can't take your opinion seriously when I see Apple documentation using the term `points` all the time, while you are saying using points causes confusion. If anything, I think pixels causes more confusion. [View Programming Guide - Points Versus Pixels](https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html) – funct7 Apr 29 '14 at 02:47
  • When you work with designers who talk about font sizes in terms of points it does get very confusing, especially when they specify "24 point" but they mean "24 pixels high from capital to descender", and to get that you need to create a UIFont using [UIFont systemFontOfSize:18.f]; Does Apple confuse points and pixels? The usage of CGPoint to mean a point in 2D space is completely consistent with geometric and computer graphics usage in general. UIFont's pointSize property returns a point size and not a height in pixels. – Adam Eberbach Apr 29 '14 at 02:53
  • Good point. However, where in my post am I ever referring to the design or font for you to come to the conclusion that I have the two concepts confused? If you've followed my link, it specifically says "the size of the rectangle is 240 by 380 points", which is basically the same thing when I said "64 points" in my original post. It also says "One point does not necessarily correspond to one pixel on the screen." I can't possibly see why you are so hung up on this pixel term. I appreciate you helping people out, but please don't give unsolicited advice. – funct7 Apr 29 '14 at 03:39
  • There are not many more explicit ways to solicit advice than by asking a question on a site devoted to questions and answers. I guess I had trouble deciphering your confusion, and came to the wrong conclusion about what you could have meant when using points as a measure of height - as they are in typography. Sorry if that upset you. – Adam Eberbach Apr 29 '14 at 03:47