web-dev-qa-db-fra.com

Image de fond en mosaïque: Puis-je le faire facilement avec UIImageView?

J'ai une image d'arrière-plan en plein écran en mosaïque, c'est-à-dire qu'elle doit être reproduite plusieurs fois horizontalement et verticalement pour en faire une grande. Comme dans les navigateurs sur les pages d'accueil laides;)

UIImageView est-il mon ami pour cela?

57
Thanks

Si je comprends bien votre question, vous pouvez utiliser colorWithPatternImage: sur UIColor, puis définir la couleur d’arrière-plan sur une UIView.

Si vous devez utiliser une variable UIImageView, vous pouvez faire de même, mais l'image que vous placez dans la vue image sera dessinée devant l'image en mosaïque.

102
Bill Dudney

Pour que l'alpha fonctionne avec l'image du motif, assurez-vous que vous avez défini les éléments suivants:

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

Pendant des années, j'ai utilisé l'approche de Bill Dudney, mais iOS 6 offre une bien meilleure solution. Et ... aujourd'hui, j'ai trouvé un moyen de faire fonctionner cela sur les anciennes versions d'iOS aussi.

  1. créer la nouvelle classe "UIImage + Tileable" (source copier/coller ci-dessous)
  2. importez ceci dans n'importe quelle classe où vous voulez un UIImageView avec une image en mosaïque. C'est une catégorie, donc elle "met à jour" tous vos UIImage en tilables, en utilisant les appels Apple standard
  3. quand vous voulez une version "mosaïque" d'une image, appelez: "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
16
Adam

J'utilise une variante de la solution de @ Rivera:

Placez ce qui suit dans une extension UIView:

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

Ensuite, vous pouvez définir le motif de fond dans le fichier storyboard/xib: Image showing how to set the colorPattern in the storyboard/xib

8
Daniel T.

Comme j'aime beaucoup Interface Builder, j'ai créé cette sous-classe UIImageView pour appliquer des fonds en mosaïque

@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

J'ai essayé de surcharger setImage: mais il semble que IB ne l'appelle pas lors du décodage d'un fichier Nib.

4
Rivera

Dans Session vidéo WWDC 2018 219 - Meilleures pratiques en matière d'images et de graphiques , l'ingénieur Apple recommande explicitement de ne pas utiliser la couleur de motif pour les arrière-plans en mosaïque:

Je recommande de ne pas utiliser de couleurs à motifs avec une propriété de couleur d'arrière-plan sur UIView. Au lieu de cela, créez un UIImageView. Attribuez votre image à cette vue. Et utilisez les fonctions de UIImageView pour définir vos paramètres de mosaïque de manière appropriée.

La méthode la plus simple et la plus simple pour créer un arrière-plan en mosaïque serait la suivante:

imageView.image = image.resizableImage(withCapInsets: .zero, resizingMode: .tile)

Ou encore plus simple, si vous utilisez un catalogue d’actifs - sélectionnez votre actif d’image de modèle et, dans l’inspecteur d’attributs, activez Découper (horizontal/vertical ou les deux), définissez les encarts sur zéro et la largeur/hauteur sur dimensions de votre image:

puis assignez simplement cette image à la vue de votre image (Interface Builder fonctionne également), mais n'oubliez pas de définir la variable contentMode de UIImageView sur .scaleToFill.

2
maxkonovalov

Version rapide de la solution de Daniel T. Vous devez toujours définir la valeur keyPath dans IB. Bien sûr, vous pourriez être plus prudent en déroulant le UIImage facultatif.

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