Center a MacGLView in a Window - objective-c

I have an cocos2D app that runs in 4/3 ratio and I want to enter fullscreen mode resizing the view to maintain the aspect ratio without showing black bars at screen sides. So, when the app enters fullscreen, I do this:
NSRect aFrame=[[NSScreen mainScreen] frame];
[glView_ setFrameSize:NSMakeSize(aFrame.size.width,aFrame.size.height*1.2)];
This way I got fullscreen wide but (as I wanted) the ratio is untouched. My problem now is that the glview is not centered on screen. It extends from left bottom point so I got my game unevenly clipped (all clipping is done at top). I've trying to use [glview setFrameOrigin] and similar to select the visible portion of the view without success.
I just want to displace my view a certain number of pixels down so it shows the center area of whole view. Is it possible?.
Thanks in advice.

You are changing the dimensions of glView_, but not its origin.
NSRect aFrame=[[NSScreen mainScreen] frame];
CGFloat x = 0.0f;
CGFloat y = aFrame.size.height;
CGFloat width = aFrame.size.width;
CGFloat height = aFrame.size.height * 1.2f;
glView_.frame = NSRectFromCGRect((CGRectMake(x, y/2 - height / 2, width, height));

Related

Make image smaller inside UIImageView

I have an UIImageView that shows and image of a creditCard, My problem is that I want to make boarders around it, so the credit card wont touch the edges of the UIimageView, I dont want to change the UIImageView position on the screen so what can I do ?
image 1
image 2
( unlike the example of the blue card it dosnt have to leave spaces only from the sides, it could shrink it from all sides )
You basically have (3) three options that can fix this.
Adjust the UIViewContentMode contentMode of the UIImageView so that it appropriately displays the image (this will only work however if the image you are using scales to fit without touching the border.
Use a UIButton instead and simply adjust the image insets until your satisfied (just disable the button or set user interaction to no here to "mimic" an image view)
Create a wrapper method that creates a new image to your desired size. Something like this should work just fine
CGSize size = CGSizeMake(< some width > , < some height >);
Then just create a new image capture with the size you've chosen
CGFloat scale = MAX(size.width/image.size.width, size.height/image.size.height);
CGFloat width = image.size.width * scale;
CGFloat height = image.size.height * scale;
CGRect imageRect = CGRectMake((size.width - width)/2.0f,
(size.height - height)/2.0f,
width,
height);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
[image drawInRect:imageRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
From here you should then be able to just apply a border width and color to get your desired result!
I guess a fourth (4th) option could be manually shrinking the image (with some photo editor) so that it renders (fits) into your image view with the appropriate padding around the image. I think the others are easier and best practice though.

IOS center bottom position view

I do the following to a loading animation, to place it at the bottom center of the screen.
CGPoint bottomCenter = CGPointMake((self.imageView.bounds.size.width / 2), (self.imageView.bounds.size.height * 0.8));
self.activityView.center = bottomCenter;
(imageView is the full screen splash image)
If the orientation is portrait, it is positioned perfectly, however turning on its side, in landscape or upside down portrait and the animation ends up miles away :S
Does anyone know the correct way to position this loading animation, its for the splash screen.
use UIDeviceOrientationIsLandscape(deviceOrientation) and UIDeviceOrientationIsPortrait(deviceOrientation) instead of deviceOrientation==X
First, look at tkanzakic's answer.
Second, don't use screen bounds, orientate the view by its parent view. If you put your view to the bottom of your parent view and you set the autoresizing mask correctly, everything will be done automatically - no need to check device orientation.
Try this code
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGPoint bottomCenter;
if (deviceOrientation == 1) {
bottomCenter = CGPointMake((screenBounds.size.width / 2), (screenBounds.size.height * 0.8));
}
else if (deviceOrientation == 4) {
bottomCenter = CGPointMake((screenBounds.size.width / 2), (screenBounds.size.height * 0.8));
}
In landscape mode you are taking wrong width and height
In landscape mode width and height also change.

How to retrieve available height considering other UIElement's height?

How can i get the available height?
I tried:
NSLog(#"%f", [self bounds].size.height);
NSLog(#"%f", [self frame].size.height);
NSLog(#"%f", [[UIScreen mainScreen] bounds].size.height);
I get always the screen's height.
But the actual height is smaller. With Informationbar on the top + Nav-Bar, the height is smaller.
EDIT:
I need to retrieve the height programmatically. Thats if there is a TabBar and my View is not always in a NavBar-Controller. Maybe there is no NavBar.
Navigation bar has a predefined height of 44 which you can never change. And by information bar, i think u mean the status bar which has a fixed height of 20. Total height of iPhone screen is 480. U do the calculations... :)
However, if you want the height of such a screen then in the nib always have status bar and navigation bar simulated and then have all the UI elements for that. After that, when you'll do
self.view.frame.size.height
you'll get the height of your view
self.view.frame.size.height;
OR
float theHeight = // one of the methods you posted
theHeight -= 44; // for nav bar
theHeight -= 20; // for status bar

resizing an NSPanel to fit a dynamic NSMatrix and a button

I have an NSMatrix that is filled dynamically with some form items. Now, I can conveniently call [theMatrix sizeToCells] and then pass it into the panel to be displayed.
Now, I want the NSPanel object which contains this NSMatrix to resize to wrap nicely around it. The NSPanel also has a button at the bottom which should be under the NSMatrix.
I have been trying many things with getting bounds and setting frames and have been having much confusion.
Is there any standard or correct way of sizing a panel to it's contents?
As a side question: Does a frame's origin refer to it's top left or bottom left? Is it always consistent?
Thanks
The origin of an NSPanel/NSWindow frame is always the bottom-left corner, it's measured from the screen origin.
Whether the origin of a view is the top left or bottom left depends on whether or not its superview is flipped. Flipped views have their bounds origin in the top left.
To do what you want, you need to get the frame size of the NSMatrix, then recalculate the layout of the panel.
Something like this (written in here, untested!):
//NSMatrix* matrix;
//NSPanel* panel;
CGFloat panelMargin = 10.0;
CGFloat matrixBottomMargin = 30.0;
[matrix sizeToCells];
NSRect matrixFrame = [matrix frame];
NSRect panelFrame = [panel frame];
NSSize newPanelSize = NSMakeSize(NSWidth(matrixFrame) + 2.0 * panelMargin,
NSHeight(matrixFrame) + 2.0 * panelMargin + matrixBottomMargin);
CGFloat yDelta = newPanelSize.height - NSHeight(panelFrame);
panelFrame = NSMakeRect(panelFrame.origin.x,
panelFrame.origin.y - yDelta,
newPanelSize.width,
newPanelSize.height);
[panel setFrame:panelFrame display:YES];

How do I pan the image inside a UIImageView?

I have a UIImageView that is displaying an image that is wider and taller than the UIImageView is. I would like to pan the image within the view using an animation (so that the pan is nice and smooth).
It seems to me that I should be able to just adjust the bounds.origin of the UIImageView, and the image should move (because the image should paint inside the view with that as its origin, right?) but that doesn't seem to work. The bounds.origin changes, but the image draws in the same location.
What almost works is to change the contentsRect of the view's layer. But this begins as a unit square, even though the viewable area of the image is not the whole image. So I'm not sure how I would detect that the far edge of the image is being pulled into the viewable area (which I need to avoid, since it displays by stretching the edge out to infinity, which looks, well, sub-par).
My view currently has its contentsGravity set to kCAGravityTopLeft via Interface Builder, if that makes a difference (Is it causing the image to move?). No other options seemed to be any better, though.
UPDATE: to be clear, I want to move the image inside the view, while keeping the view in the same spot.
I'd highly recommend enclosing your UIImageView in a UIScrollView. Have the UIImageView display the full image, and set the contentSize on the UIScrollView to be the same as your UIImageView's size. Your window into the image will be the size of the UIScrollView, and by using scrollRectToVisible:animated: you can pan to particular areas on the image in an animated fashion.
If you don't want scroll bars to appear, you can set the showsHorizontalScrollIndicator and showsVerticalScrollIndicatorproperties to NO.
UIScrollView also provides pinch-zooming functionality, which may or may not be useful to you.
Brad Larson pointed me down the right road with his suggestion to put the UIImageView inside a UIScrollView.
In the end I put the UIImageView inside of a UIScrollView, and set the scrollView's contentSize and the imageView's bounds to be the same size as the image in the UIImage:
UIImage* image = imageView.image;
imageView.bounds = CGRectMake(0, 0, image.size.width, image.size.height);
scrollView.contentSize = image.size;
Then, I can animate the scrollView's contentOffset to achieve a nice panning effect:
[UIView beginAnimations:#"pan" context:nil];
[UIView setAnimationDuration:animationDuration];
scrollView.contentOffset = newRect.origin;
[UIView commitAnimations];
In my particular case, I'm panning to a random space in the image. In order to find a proper rect to pan to and a proper duration to get a nice constant speed, I use the following:
UIImage* image = imageView.image;
float xNewOrigin = [TCBRandom randomIntLessThan:image.size.width - scrollView.bounds.size.width];
float yNewOrigin = [TCBRandom randomIntLessThan:image.size.height - scrollView.bounds.size.height];
CGRect oldRect = scrollView.bounds;
CGRect newRect = CGRectMake(
xNewOrigin,
yNewOrigin,
scrollView.bounds.size.width,
scrollView.bounds.size.height);
float xDistance = fabs(xNewOrigin - oldRect.origin.x);
float yDistance = fabs(yNewOrigin - oldRect.origin.y);
float hDistance = sqrtf(powf(xDistance, 2) + powf(yDistance, 2));
float hDistanceInPixels = hDistance;
float animationDuration = hDistanceInPixels / speedInPixelsPerSecond;
I'm using a speedInPixelsPerSecond of 10.0f, but other applications might want to use a different value.