Tiled Background Image: Can I do that easily with UIImageView?
IphoneUiimageviewIphone Problem Overview
I have a fullscreen background image that is tiled, i.e. it has to be reproduced a few times horizontally and vertically in order to make a big one. Like in the browsers on ugly home pages ;)
Is UIImageView my friend for this?
Iphone Solutions
Solution 1 - Iphone
If I understand your question correctly you can use colorWithPatternImage:
on UIColor
then set the background color on a UIView
.
If you must use a UIImageView
you can do the same but whatever image you place in the image view will draw in front of the tiled image.
Solution 2 - Iphone
To get alpha to work with pattern image, make sure you have the following set:
view.backgroundColor = [UIColor colorWithPatternImage:aImage];
view.layer.opaque = NO;
Solution 3 - Iphone
For years I used Bill Dudney's approach, but iOS 6 has a much better solution. And ... today I found a way to make this work on old versions of iOS too.
- create the new class "UIImage+Tileable" (copy/paste source below)
- import this in any class where you want a UIImageView with tileable image. It's a category, so it "upgrades" all your UIImage's into tileable ones, using standard Apple calls
- when you want a "tiling" version of an image, call: "image = [image imageResizingModeTile]"
UIImage+Tileable.h
#import <UIKit/UIKit.h>
@interface UIImage (Tileable)
-(UIImage*) imageResizingModeTile;
@end
UIImage+Tileable.m
#import "UIImage+Tileable.h"
@implementation UIImage (Tileable)
-(UIImage*) imageResizingModeTile
{
float iOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if( iOSVersion >= 6.0f )
{
return [self resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeTile];
}
else
{
return [self resizableImageWithCapInsets:UIEdgeInsetsZero];
}
}
@end
Solution 4 - Iphone
In WWDC 2018 video session 219 - Image and Graphics Best Practices, Apple engineer explicitly recommends not to use the pattern color for tiling backgrounds:
> I recommend not using patterned colors with a background color property on UIView. Instead, create a UIImageView. Assign your image to that image view. And use the functions on UIImageView to set your tiling parameters appropriately.
So the best and simplest way to create a tiled background would be like this:
imageView.image = image.resizableImage(withCapInsets: .zero, resizingMode: .tile)
Or even simpler, if you use asset catalog – select your pattern image asset and, in the Attributes inspector, enable Slicing (Horizontal/Vertical or both), set the insets to zero, and width/height to the dimensions of your image:
https://i.stack.imgur.com/BJ0ax.png" width="260">
then simply assign this image to your image view (Interface Builder works, too), just don't forget to set the UIImageView's contentMode
to .scaleToFill
.
Solution 5 - Iphone
I use a variation of @Rivera's solution:
Put the following in a UIView extension:
- (void)setColorPattern:(NSString *)imageName
{
[self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:imageName]]];
}
Then you can set the background pattern in the storyboard/xib file:
Solution 6 - Iphone
As I really like Interface Builder I created this UIImageView
subclass to apply tiled backgrounds:
@interface PETiledImageView : UIImageView
@end
@implementation PETiledImageView
- (void)awakeFromNib
{
[super awakeFromNib];
UIImage * imageToTile = self.image;
self.image = nil;
UIColor * tiledColor = [UIColor colorWithPatternImage:imageToTile];
self.backgroundColor = tiledColor;
}
@end
I tried overriding setImage:
but it seems IB doesn't call it when decoding a Nib file.
Solution 7 - Iphone
Swift version of Daniel T's solution. You still need to set the keyPath value in IB. Of course you could be more careful unwrapping the Optional UIImage.
extension UIView {
var colorPattern:String {
get {
return "" // Not useful here.
}
set {
self.backgroundColor = UIColor(patternImage: UIImage(named:newValue)!)
}
}
}