CGRect positioning according to center point - ios

I'm trying to create multiple views for an iPad app. First I created a menu view and then a sub-menu view with coordinates according to menu. So it looks like this:
What I did:
self.view = [[UIView alloc] initWithFrame:CGRectMake(self.parentViewController.view.frame.size.width, 0, 150, screenHeight)];
But now on sub-menu I'm trying to create the content view, which is a UINavigationController. Trying to do the same thing, I get this result:
What I'm doing (this time creating the frame on sub-menu view controller):
CGRect frame = CGRectMake(self.view.frame.origin.x + self.view.frame.size.width,
0,
[[UIScreen mainScreen] bounds].size.width - self.view.frame.origin.x - self.view.frame.size.width,
[[UIScreen mainScreen] bounds].size.height);
It's pretty self-explanatory but, I just get the sub-menu origin and add its width so I can get the right edge coordinate.
After a lot of attempts I managed to get it working, because I noticed that the CGRectMake is using the center of the UINavigationController view to arrange its position. So the following code:
CGRect frame = CGRectMake(self.view.frame.origin.x + self.view.frame.size.width + 259,
0,
[[UIScreen mainScreen] bounds].size.width - self.view.frame.origin.x - self.view.frame.size.width,
[[UIScreen mainScreen] bounds].size.height);
Yields the right position.
What's going on? I thought CGRectMake origin would always be top-left, but on this particularly view is actually top-middle (or middle-middle, not sure.) What am I doing wrong?
EDIT1:
Here's the console output for the frame with right position:
Notice how the nav bar is now positioned right:
But the x-coord is not 250 (as it should be, because menu.width + sub-menu.width = 250.)
EDIT2:
I eventually gave up. The problem was with the automatically generated UINavigationBar, which is created by the UINavigationViewController. I can't seem to figure out how to configure it. I'm gonna leave the question open in case someone knows the answer.

Center of a CGRect is a CGPoint created from the origin.x + ( size.width / 2 ) and origin.y + ( size.height / 2 ).

UIButton* btn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 70, 70)];
btn.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
This will make the button in the center no matter what the device is

CGRectMake just creates an stucture of (x,y, witdh, height).
It your part to set the correct values.

Related

Custom view with CGRectMake location x and y providing incorrect view

Previous i am using Xcode 6.4 or below, In that I didn't notify this type issues. but now I am getting noticeable problems in Xcode 7.2 in related CGRectMake x,y Position.
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
UIView *smallView=[[UIView alloc]initWithFrame:CGRectMake(screenWidth/2, screenHeight/2, 100, 100)];
smallView.backgroundColor=[UIColor redColor];
[self.view addSubview:smallView];
NSLog(#"%f",smallView.frame.origin.x);// 137.500000
above snip code, the position of x & y not perfect. the below image is output .
but if i add center=self.view.ceter It will come to center. the output is
smallView.center=self.view.center;
the problem is , in both case x & y position values same ,
NSLog(#"%f\n%f\n%f\f%f ",screenWidth/2,screenHeight/2,self.view.center.x,self.view.center.y);
Why they will show different result, how can i do without using center property. or Shall go for Autolayout .

UIScrollView Height and width

I am facing one strange problem, using the below code I am making the UIScrollView to full screen.
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
CGRect scrollFrame = CGRectMake(0, 0, screenWidth, screenHeight);
self.imageHostScrollView.frame = scrollFrame;
NSLog(#"Scroll Height: %f, Width: %f",screenHeight,screenWidth);
The problem I am facing when the iPad is in the Portrait mode, the height will be big and width will be small, instead I am getting height smaller and width bigger (same happens in Landscape mode also).
Portrait mode the value I am getting is
Scroll Height: 768.000000, Width: 1024.000000
In Landscape mode the value I am getting is
Scroll Height: 1024.000000, Width 768.000000
Can anyone help me
The problem is that the way you're setting the self.imageHostScrollView.frame is silly. You are effectively hard-coding assumptions about the screen into the frame of a view — two things that are completely unrelated to one another.
Instead, use auto layout to pin the edges of the scroll view to the edges of the window. That way, whatever the window may do from now on — making no assumptions about what that may be — the scroll view will continue to fill it exactly.

How to draw View Controller from the bottom

I am trying to develop an app in Xcode. I am new in Objective C programming but so far I did OK. Today I got my first problem. I am trying to draw a transparent VC (View Controller) from the bottom up but I do not know how I can accomplish this. I know that drawing in iPhone begins from 0,0 coordinates from top left corner going right and down. Is there a way to kind of cheat and draw the VC from the bottom to top 70% covering the screen, just like the tools menu when swipe up on iPhone screen in iOS 7.x.x
Thanks in advance.
Heres one solution:
Create the view as a subview of the main view in this controller.
self.rolloutView = [[UIView alloc]initWithFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width, heightYouWant)];
When the user takes the action, call this function
-(void)toggleView:(id)sender
{
__block CGRect frame = self.rolloutView.frame;
// Check if the frame's origin.y is at the bottom of the screen
if(self.rolloutView.frame.origin.y == [[UIScreen mainScreen] bounds].size.height){
// if it is, reduce it by the height of the view you eventually want
frame.origin.y = [[UIScreen mainScreen] bounds].size.height-heightYouWant ;
}
else{
// else push it down again
frame.size.height = [[UIScreen mainScreen] bounds].size.height;
}
[UIView animateWithDuration:.3
animations:^{
self.rolloutView.frame = frame;
}
completion:nil];
}
I have not compiled the code but it should give you the idea on what i am suggesting

AnimateWithDuration disables userInteraction on UIView

I'm adding a child view on top of one of my views, and animating it so that it starts at the bottom of the screen and ends up at the top of the screen by using animateWithDuration. And that all works fine except that after animateWithDuration is complete the view on top has no user interaction and the view below still has user interaction. If I remove animateWithDuration, and just start the child view at it's normal position the user interaction works how I would expect it too, which is why I think animateWithDuration is the problem.
Here's my code:
UIViewController *viewController = [[CCouponDetailViewController alloc] init];
[[viewController view] setBounds:CGRectMake(0, ([UIScreen mainScreen].bounds.size.height * -1), viewController.view.bounds.size.width, viewController.view.bounds.size.height)];
[self addChildViewController:viewController];
[self.view addSubview:viewController.view];
CGRect newFrame = viewController.view.frame;
newFrame.origin.x = 0;
newFrame.origin.y = ([UIScreen mainScreen].bounds.size.height * -1);
[UIView animateWithDuration:1.0
animations:^{
viewController.view.frame = newFrame;
}
completion:^(BOOL finished){
[viewController didMoveToParentViewController:self];
}
];
Another question I have (Not really important just curious) is that in newFrame I'm setting the y to the same thing as it is when I initially set the bounds, but yet it moves. I would have expected newFrame to require a y value of "0" but when I did that nothing happened. Just wondering why that is.
I'll actually go backwards on this one...
"Another question I have (Not really important just curious) is that in newFrame I'm setting the y to the same thing as it is when I initially set the bounds, but yet it moves. I would have expected newFrame to require a y value of "0" but when I did that nothing happened. Just wondering why that is."
This is actually a very important question for you to have answered, because it has a lot to do with why your code isn't working. You're misunderstanding some very important concepts.
First off, the bounds of a UIView determine its position entirely in relation to itself. The frame determines the UIView's position within its superview. In your code, you're originally setting the view's bounds, not the frame --
[[viewController view] setBounds:CGRectMake(0, ([UIScreen mainScreen].bounds.size.height * -1), viewController.view.bounds.size.width, viewController.view.bounds.size.height)];
-- so you're not at all originally determining the view's place within its superview, only in relation to itself.
Essentially, you're ending up with a CCouponDetailViewController view with a 0x0 frame, but since you haven't specified that you want your UIView to clip its subviews, the portions of your CCouponDetailViewController view are not actually on top of their view, but visible and hanging over the UIView's bounds. The reason they aren't selectable is because they're not actually within the UIView.
So to fix this, set your UIView's initial frame instead of setting a bounds (I've editing the initial frame to start at the bottom of the screen like you're trying to do. I don't understand the height x -1 thing you're trying to do, by the way...) :
[[viewController view] setFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height, viewController.view.bounds.size.width, viewController.view.bounds.size.height)];
Secondly, you're setting your new frame incorrectly. You can't set the CGRect this way:
CGRect newFrame = viewController.view.frame;
newFrame.origin.x = 0;
newFrame.origin.y = ([UIScreen mainScreen].bounds.size.height * -1);
Instead, set it using CGRectMake (And, again, I edited the y value so that the view ends up at the top of the screen like you're trying to do):
CGRect newFrame = CGRectMake(0, 0, viewController.view.frame.width, viewController.view.frame.height);

On iOS, what is the best way to set up a subview if we really would like to do initWithCenterAndSize?

For example, if we are to draw a 100 x 100 pixel circle on the main view which covers up the whole screen on the iPad, then instead of using initWithFrame like following 2 steps in viewDidLoad:
UINodeView *nodeView = [[UINodeView alloc] initWithFrame:
CGRectMake(x, y, NSNodeWidth, NSNodeHeight)];
nodeView.center = CGPointMake(x, y);
because x and y is more elegantly as self.view.bounds.size.width / 2 to horizontally center the circle, instead of self.view.bounds.size.width / 2 - NSNodeWidth / 2. Is init by a frame first, and then reset the center a good way, or is there a better way, if there is a initWithCenterAndSize?
That's a fine way of doing it :)
I would have gone for generating the positioned frame first to avoid the extra method call but that's just a matter of personal preference :)
If you're using this alot in your app you could make a category on UIView that implements this (warning, untested code :)
- (id)initWithCenter:(CGPoint)point size:(CGSize)size {
CGRect frame = CGRectMake(point.x-size.width/2,
point.y-size.height/2,
size.width,
size.height);
return [self initWithFrame:frame];
}
I usually do this:
UINodeView *nodeView = [[UINodeView alloc] initWithFrame:
CGRectMake(0, 0, NSNodeWidth, NSNodeHeight)];
nodeView.center = CGPointMake(x, y);
It looks nice and clear.

Resources