In our iOS app, we have subclassed a UISlider in order to use a custom design. However, no matter what we try, the images used in the UISlider come out distorted. For instance, the original thumb rect is 156x44. We have overridden this to be 15x22, which results in a blown up image. Other permutations result in the thumb going off-track, and still blown up. How can we correctly set the image size for the thumb and track, by using padding on the images or by overriding the appropriate functions?
I think that UISlider was designed one resolution and one only, and making the elements smaller, will negatively affect user experience. But if you really want to, try one of these:
Use the bigger images, but set the transform property of an UISlider instances to some CGAffineTransformMakeScale(scaleX, scaleY).
Add transparent padding to your images, so they look small, but are actually of a proper size.
That is, if you really want your UISlider smaller. If all you are bothered with is the distortion caused, but automatic upscaling, consider loading UIImages as stretchable, f.i. with
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets // iOS >=5.0
or
- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight // iOS <5.0
Related
Out of sheer interest:
Is there any difference, specifically in (theoretic) performance or memory usage between using a UIImage of 25x25 pixels, square, one color, png on the one hand, or a UIView of the same size and color?
Consider the Unread bullet in Mail.app. Would you use an image for that? Or a UIView with rounded edges?
An image takes more space, and resided in a UIImageview, and has a resolution dependency, but on the other hand, once it is loaded, it wouldn't make too much difference, would it?
If you use UIImageView then it requires image. Where if you use UIView you not need image, so it makes your application light weight. Second thing, large image takes more memory to load. So, it is always beneficial to use UIView instead of image wherever possible! It keeps your application light weight and can give better performance!
An UIImageView, being a subclass of UIView, will instantiate a regular view with all the extension that UIKit developers have built to support displaying an image inside a plain UIView. By doing that you're only creating an extended (aka possibly heavier) version of a standard UIView.
That said, using an UIView for simple UI elements (like Mail.app's bullet icon) will also allow you to forget about the resolution of the graphical asset since you don't have to care about #2x or #3x resolutions resulting also in a smaller project size.
Of course you'll only save kilobytes when it comes to simple shapes, but reusing this pattern all across the app will benefit you exponentially in the long term.
When you put a UIImage into a UIImageView that is smaller than the view, and the content mode of the view is ScaleToFit, iOS enlarges the bitmap, as expected. What I have never expected is that it blurs the edges of the pixels it has scaled-up. I can see this might be a nice touch if you're looking at photographs, but in many other cases I want to see those nasty, hard, straight edges!
Does anyone know how you can configure a UIImage or UIImageView to enlarge with sharp pixel edges? That is: Let it look pixellated, not blurred.
Thanks!
If you want to scale up any image in UIImageView with sharpen edge, use the following property of CALayer.
imageview.layer.magnificationFilter = kCAFilterNearest;
It seems that magnificationFilter affects an interpolation method of contents of UIView. I recommend you to read an explanation of the property in CALayer.h.
/* The filter types to use when rendering the `contents' property of
* the layer. The minification filter is used when to reduce the size
* of image data, the magnification filter to increase the size of
* image data. Currently the allowed values are `nearest' and `linear'.
* Both properties default to `linear'. */
#property(copy) NSString *minificationFilter, *magnificationFilter;
I hope that my answer is useful for you.
I just started learning obj-c the other day and i'm putting together a crappy game as practice. I have an IMG as a main character to the game and every time this character hits certain obstacles, i wanted the size of the image to change (decrease or increase depending on the circumstance).
I used photoshop the change the size of the images to the appropriate sizes but for some reason, when i run the game, the images change when i want them too, but they are way smaller than the size i set them to in photoshop......
any ideas?
i don't think its necessary to post my code for something as simple as this, right? its just a simple "if" statement followed by the instance and the UIimage named for the image name...
I assume you display the image in an UIImageView? Or do you use SpriteKit? If you use an UIImageView the image is actually automatically scaled to the size of the UIImageView.
Therefore you would just change the size of the UIImageView (you can of course also change the image inside the UIImageView.
If you are using SpriteKit, you have to remember, that your are probably testing on a 'retina' device and for this reason the image's width and height is divided by 2 (the real resolution of the current iPhone 5/5s is 1136x640 and not 568x320 !
What is an equal value of
resizableImageWithCapInsets: for stretchableImageWithLeftCapWidth:0 topCapHeight:0?
Also, Is there any simple way to convert the values from stretchableImageWithLeftCapWidth to resizableImageWithCapInsets?
Because the stretchableImageWithLeftCapWidth method was deprecated in iOS 5.
Thanks
I guess your looking for resizableImageWithCapInsets:UIEdgeInsetsZero?
By using:
stretchableImageWithLeftCapWidth:0 topCapHeight:0
You're telling iOS that you want the entire image to be vertically stretchable and you want the entire image to also be horizontally stretchable (itals copied directly from Apple docs). In other words, no part of the image will be preserved unstretched.
In converting your code to use the new method introduced in iOS 5, though, you'll have to keep in mind that the new method works differently than the old one when it determines how to resize the image not contained in the caps (hence the move away from using "stretch" in the method name itself).
While the old method used pure (and not always efficient) scaling of every pixel not contained in the caps as a whole, the new method defaults to the more efficient tiling approach. As a consequence, the results between old and new methods will be very different if the part of the image you're stretching (the part not contained in the caps) measures more than one pixel in the direction(s) being stretched and isn't uniform.
While you have not provided screenshots of the actual image you are working with or the results you're getting, which makes it impossible to tell you exactly why you're not getting the results you want, it does sound like you specifically want your image to be resized with the UIImageResizingModeStretch resizing mode (rather than the default tiling mode). If so, it's likely that you should be using this method instead:
resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:
The answer to your second question also depends on how you want the stretchable part of your image stretched.
Heuristically:
If your old caps were non-zero and the portion being stretched was either 1x1 pixel or at least uniform in the direction(s) of stretching, you'd probably be able to use UIEdgeInsetsMake(*top*, *left*, *bottom*, *right*) with your LeftCap value as left and right and your TopCap value as top and bottom, given that the old method assumed you wanted to stretch the image symmetrically.
If your old caps were 0 or the portion being stretched was larger than 1x1 pixel in any direction(s) of resized and non-uniform, you could still convert the caps in the same way but you'd want to use the method variant that allows you to control the resizingMode.
I displays a splash Screen when my app loads,There is a background image in the splash screen,I problem is how can I make fit this image in all types of blackberry models?
Keep in mind that many BlackBerry devices have different screen resolutions and even different aspect ratios. So if you just use a single image and resize (stretch and/or squish) it to fit the current screen, you're going to distort the image (or pattern). As I see it, there are two main approaches:
1) Use a different image for each screen resolution. There are about 7 different resolutions that cover most of the in-market devices (240x260, 240x320, 320x240, 360x400, 360x480, 480x320, 480x360)
2) If it's a regular background pattern as opposed to a picture or logo, just have one image in the app that's big enough to cover the largest screen size (480x360) and for all other screen sizes just clip it. In fact, I think this should happen automatically if you just set the background image - anything that can't be displayed on the screen will be clipped.
While approach #2 is better in terms of reducing application size, I'm going to guess that since you're asking this question the background you're thinking of using isn't a regular pattern.
I think the simplest method would be to use the setBorder method of whatever screen/field needs a stretched background. For example:
Border b = BorderFactory.createBitmapBorder (new XYEdges (), bitmap);
field.setBorder(b);
In my experience this results in the background image being stretched and provides the simplest method for fitting the size you need. I have only ever used it for fields though and never a MainScreen so it might not work for you.