简体   繁体   English

平铺背景图片:我可以使用UIImageView轻松完成吗?

[英]Tiled Background Image: Can I do that easily with UIImageView?

I have a fullscreen background image that is tiled, ie 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? UIImageView是我的朋友吗?

If I understand your question correctly you can use colorWithPatternImage: on UIColor then set the background color on a UIView . 如果我正确理解你的问题你可以使用colorWithPatternImage:UIColor然后在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. 如果必须使用UIImageView ,则可以执行相同的操作,但放置在图像视图中的任何图像都将绘制在平铺图像的前面。

To get alpha to work with pattern image, make sure you have the following set: 要使alpha与模式图像一起使用,请确保您具有以下设置:

view.backgroundColor = [UIColor colorWithPatternImage:aImage];
view.layer.opaque = NO;

For years I used Bill Dudney's approach, but iOS 6 has a much better solution. 多年来我一直使用Bill Dudney的方法,但iOS 6有更好的解决方案。 And ... today I found a way to make this work on old versions of iOS too. 而且......今天我找到了一种方法,可以在旧版本的iOS上使用它。

  1. create the new class "UIImage+Tileable" (copy/paste source below) 创建新类“UIImage + Tileable”(下面的复制/粘贴源)
  2. import this in any class where you want a UIImageView with tileable image. 在任何你想要带有tileable图像的UIImageView的类中导入它。 It's a category, so it "upgrades" all your UIImage's into tileable ones, using standard Apple calls 这是一个类别,因此它使用标准的Apple调用将所有UIImage“升级”为可平铺的
  3. when you want a "tiling" version of an image, call: "image = [image imageResizingModeTile]" 当你想要一个图像的“平铺”版本时,请调用:“image = [image imageResizingModeTile]”

UIImage+Tileable.h 的UIImage + Tileable.h

#import <UIKit/UIKit.h>

@interface UIImage (Tileable)

-(UIImage*) imageResizingModeTile;

@end

UIImage+Tileable.m 的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

I use a variation of @Rivera's solution: 我使用了@Rivera解决方案的变体:

Put the following in a UIView extension: 将以下内容放在UIView扩展中:

- (void)setColorPattern:(NSString *)imageName
{
    [self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:imageName]]];
}

Then you can set the background pattern in the storyboard/xib file: 然后,您可以在storyboard / xib文件中设置背景模式: 该图显示了如何在storyboard / xib中设置colorPattern

As I really like Interface Builder I created this UIImageView subclass to apply tiled backgrounds: 我真的很喜欢Interface Builder,我创建了这个UIImageView子类来应用平铺背景:

@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. 我尝试重写setImage:但似乎IB在解码Nib文件时不会调用它。

In WWDC 2018 video session 219 - Image and Graphics Best Practices , Apple engineer explicitly recommends not to use the pattern color for tiling backgrounds: WWDC 2018视频会话219 - 图像和图形最佳实践中 ,Apple工程师明确建议不要使用图案颜色来平铺背景:

I recommend not using patterned colors with a background color property on UIView. 我建议不要在UIView上使用带有背景颜色属性的图案颜色。 Instead, create a UIImageView. 而是,创建一个UIImageView。 Assign your image to that image view. 将图像分配给该图像视图。 And use the functions on UIImageView to set your tiling parameters appropriately. 并使用UIImageView上的函数来适当地设置切片参数。

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: 或者甚至更简单,如果您使用资产目录 - 选择您的图案图像资源,并在属性检查器中,启用切片 (水平/垂直或两者),将插图设置为零,并将宽度/高度设置为图像的尺寸:

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 . 然后只需将此图像分配给图像视图(Interface Builder也可以),只是不要忘记将UIImageView的contentMode设置为.scaleToFill

Swift version of Daniel T's solution. Swift版Daniel T的解决方案。 You still need to set the keyPath value in IB. 您仍需要在IB中设置keyPath值。 Of course you could be more careful unwrapping the Optional UIImage. 当然,您可以更小心地展开Optional UIImage。

extension UIView {
    var colorPattern:String {
        get {
            return ""  // Not useful here.
        }
        set {
            self.backgroundColor = UIColor(patternImage: UIImage(named:newValue)!)
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM