Cocoa iOS Make CGPoints "Bigger" in UIView - ios

Is it possible to make the default CGPoint size for an iOS app "bigger"?
For example, the iPhone's main view is 320 points wide - is it possible to change that to, say, 100 points, and base all calculations on that 100 (as in still be able to use CGRectMake, get sizes etc. normally).
So does anyone know how to subclass UIView in such a way as to make the above work, and, more importantly, would Apple allow it?
Thanks for your time!

Apply a CGAffineTransformMakeScale(320/100, 320/100) transform to your view so that it is scaled, and 100 points will be scaled to 100 * (320/100) = 320 points wide.
Or course, don't use magic numbers like above, but use some constant for the value 100 and something like [UIScreen mainScreen].applicationFrame.size.width (or view.window.screen.applicationFrame.size.width or anything similar) to get the width of the screen instead of the value 320 (because magic numbers are bad, and we never know if the size of the screen will change in any future like the height just changed with iPhone5)

Have a look at UIViews transform property. But this is probably a bad idea: If you rescale your coordinate system, almost all your views are going to be misaligned with the screen's pixels. This will lead to blurry display of text, lines and other graphics.
Why would you want to do this in the first place?

Related

SpriteKit Animation - Keeping Sprites Fixed

I am animating some frames of a monster jumping and swinging a sword, and the frames are such that the width gets bigger or smaller as he swings the sword (the monster standing is 500 width, but his sword, fully extended to the left, adds another 200 width, thus he varies from 500 to 700 or more in width)
I originally took each frame, which is on a transparent background, and used the Photoshop magic wand tool to select just the monster. I then saved these frames like that, and when I used them to animate, the monster warped and changed sizes (it looked bad).
The original frames had a large 1000 x 1000 transparent background surrounding him, and as a result it always kept him "bound" so that it never warped.
My question is what is a good way to create frames of animation where the sprite inside might change size or width as he's moving so that there is no warping?
If I have to use a large border of transparent pixels, is that the recommended approach? I'm noticing that for my animation, each monster takes up about 3 - 5MB. I plan on potentially having a lot of these people ultimately, so i'm wondering if this is the best approach (using large 900 x 900 images all the time, plus I'll be using more for 2x and 1x). So all of this seems like it could spiral out of control to 4 or 5GB.
What are other people doing when making animations that require different poses and positions? Just fixing the frames with borders that are as small as possible?
Thanks!
You should probably change the approach to animation and use inverse kinematics instead. Take a look at this and Ray's tutorial.

Should we use integer strictly when we layout controls in iOS? Why?

I need to draw a line on the screen. The designer tell me to set the height of line to 2.5 pt. I'm wondering if it's acceptable to use decimal here.
I know it will be better if we use integer as the size or position of a UIView. But I can't tell why. I didn't find any convincing document about it.
So could anyone explain it or find something for me?
The only problem I know is UILabel with decimal size will be blurry. Is there any other problem like performance problem would happen?
As per your case it's just about half point which in my opinion should be ok. I often find that in storyboards my frames get moved 0.5 point up or down when I have lot of UI elements and sometimes constraints just get confused.
Additionally: the easiest scenario when your frame could be positioned at "some 0.5 point" is if you use a constraint to centre your view in it's superview. In this case the default x or y frame position could easily end up being "some 0.5 point". So it can happen often times and could be done by Xcode itself, so that's why I think your view will be just fine.
As stated previous in comments those points are CGFloat. What we have now is 1x, 2x and 3x resolutions. So there will always be the need for some calculations for at least one of the devices.
You may also look at this Screen resolutions guide to see all the time when up sampling and downsampling occurs.

Suggestions for drawing a complex hierarchy at multiple sizes

I am trying to think of a way to render a sub-hierarchy that is somewhat complex, and would look good (crisp) when drawn at multiple scales.
I would expect there to be some container view with a size, and this subview could be constrained within it and drawn properly.
If it helps think of a hierarchy like a calculator keypad or computer keyboard even:
You would have a keyContainer view, and a bunch of key views (or layers) of various sizes and positions.
Suppose I wanted this to be drawn in a container that was 320 x 320. I was thinking if I knew the ratio of w:h for each key and I knew the ratio of a key's width to the width of the whole container, then I could work out the sizes and positions for the key. I've found in practice the math seems to introduce a lot of rounding errors and you end up on off-pixel boundaries so the final rendering does not look great.
So how would you tackle a problem like this?
Thanks for any ideas.

Getting the same coordinates from UIScrollView whether it's zoomed or not

Is it possible to get the same coordinates from UIScrollView whether it's zoomed or not.
That is, For example, consider a plain screen of 320.0F and 480.0F.
Tap on a point; view will give me something like (60.0F, 80.0F).
Zooming-in or zooming-out on the view so that it will have either bigger or smaller zoom scale but making sure the zoomed area to contain the point that was tapped which was (60.0F, 80.0F) according to previous zoom scale.
Tap on the point again, the view will give me different coordinate value.
The Thing is, I want to have the same coordinate value whether the view is zoomed or not. The idea is simple. I want to show images zoomed & interactive without changing its coordinate. Considering an UIScrollView applied of the idea with its height of 1.0 and width of 0.66, I think there would be some pros programming this way, when making an interactive app without using OpenGL, cocos2d or whatever 3D engines out there.
Do you guys have any idea if it's supported or not? Either case, please don't wait any second to reply. Thanks
You can calculate it by yourself using content size as follows,
x = (original_Width/ width_after_zooming) * point.x
y = (original_height/ height_after_zooming) * point.y

What is the secret behind "contentScaleFactor" of UIView when used with CATiledLayer?

Greetings,
I'm working on an application inspired by the "ZoomingPDFViewer" example that comes with the iOS SDK. At some point I found the following bit of code:
// to handle the interaction between CATiledLayer and high resolution
// screens, we need to manually set the tiling view's
// contentScaleFactor to 1.0. (If we omitted this, it would be 2.0
// on high resolution screens, which would cause the CATiledLayer
// to ask us for tiles of the wrong scales.)
pageContentView.contentScaleFactor = 1.0;
I tried to learn more about contentScaleFactor and what it does. After reading everything of Apple's documentation that mentioned it, I searched Google and never found a definite answer to what it actually does.
Here are a few things I'm curious about:
It seems that contentScaleFactor has some kind of effect on the graphics context when a UIView's/CALayer's contents are being drawn. This seems to be relevant to high resolution displays (like the Retina Display). What kind of effect does contentScaleFactor really have and on what?
When using a UIScrollView and setting it up to zoom, let's say, my contentView; all subviews of contentView are being scaled, too. How does this work? Which properties does UIScrollView modify to make even video players become blurry and scale up?
TL;DR: How does UIScrollView's zooming feature work "under the hood"? I want to understand how it works so I can write proper code.
Any hints and explanation is highly appreciated! :)
Coordinates are expressed in points not pixels. contentScaleFactor defines the relation between point and pixels: if it is 1, points and pixels are the same, but if it is 2 (like retina displays ) it means that every point has two pixels.
In normal drawing, working with points means that you don't have to worry about resolutions: in iphone 3 (scaleFactor 1) and iphone4 (scaleFactor 2 and 2x resolution), you can use the same coordinates and drawing code. However, if your are drawing a image (directly, as a texture...) and just using normal coordinates (points), you can't trust that pixel to point map is 1 to 1. If you do, then every pixel of the image will correspond to 1 point but 4 pixels if scaleFactor is 2 (2 in x direction, 2 in y) so images could became a bit blurred
Working with CATiledLayer you can have some unexpected results with scalefactor 2. I guess that having the UIView a contentScaleFactor==2 and the layer a contentScale==2 confuse the system and sometimes multiplies the scale. Maybe something similar happens with Scrollview.
Hope this clarifies it a bit
Apple has a section about this on its "Supporting High-Resolution Screens" page in the iOS dev documentations.
The page says:
Updating Your Custom Drawing Code
When you do any custom drawing in your application, most of the time
you should not need to care about the resolution of the underlying
screen. The native drawing technologies automatically ensure that the
coordinates you specify in the logical coordinate space map correctly
to pixels on the underlying screen. Sometimes, however, you might need
to know what the current scale factor is in order to render your
content correctly. For those situations, UIKit, Core Animation, and
other system frameworks provide the help you need to do your drawing
correctly.
Creating High-Resolution Bitmap Images Programmatically If you
currently use the UIGraphicsBeginImageContext function to create
bitmaps, you may want to adjust your code to take scale factors into
account. The UIGraphicsBeginImageContext function always creates
images with a scale factor of 1.0. If the underlying device has a
high-resolution screen, an image created with this function might not
appear as smooth when rendered. To create an image with a scale factor
other than 1.0, use the UIGraphicsBeginImageContextWithOptions
instead. The process for using this function is the same as for the
UIGraphicsBeginImageContext function:
Call UIGraphicsBeginImageContextWithOptions to create a bitmap
context (with the appropriate scale factor) and push it on the
graphics stack.
Use UIKit or Core Graphics routines to draw the content of the
image.
Call UIGraphicsGetImageFromCurrentImageContext to get the bitmap’s
contents.
Call UIGraphicsEndImageContext to pop the context from the stack.
For example, the following code snippet
creates a bitmap that is 200 x 200 pixels. (The number of pixels is
determined by multiplying the size of the image by the scale
factor.)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(100.0,100.0), NO, 2.0);
See it here: Supporting High-Resolution Screens

Resources