2009-03-25 12 views
8

Voglio essere in grado di un oggetto UI come un UIImageView e affiancare un'immagine al suo interno.Come posso utilizzare CGContextDrawTiledImage per affiancare un'immagine?

Sono stato in grado di utilizzare CGContextDrawTiledImage per aggiornare lo sfondo nella finestra principale, ma non una visualizzazione di immagine. Posso farlo se modifico la funzione drawRect all'interno della classe MainView.

Mi sento vicino, ma mi manca ancora qualcosa. Qualcuno può indicarmi la giusta direzione?

- (void)drawRect:(CGRect)rect { 

CGImageRef image = CGImageRetain(currentImage.CGImage); 

CGRect imageRect; 
imageRect.origin = CGPointMake(160, 240); 
imageRect.size = CGSizeMake(320.0, 480.0); 

CGContextRef uiContext = UIGraphicsGetCurrentContext(); 

CGContextClipToRect(uiContext, CGRectMake(0.0, 0.0, rect.size.width, rect.size.height)); 

CGContextDrawTiledImage(uiContext, imageRect, image); 

}

+1

Questo è molto vecchia questione, lo so: nel caso in cui qualcuno si imbatte qui: non si deve ignorare drawRect di UIImageView - credo che sia l'unica sottoclasse UIView in UIKit con questa restrizione ... –

risposta

17

Diciamo che hai un CGImageRef per l'immagine che si desidera piastrelle chiamato tileImage e UIImageView chiamato imageView. Quello che devi fare è creare un UIImage da assegnare alla proprietà image di imageView. Potete farlo in questo modo:

CGSize imageViewSize = imageView.bounds.size; 
UIGraphicsBeginImageContext(imageViewSize); 
CGContextRef imageContext = UIGraphicsGetCurrentContext(); 
CGContextDrawTiledImage(imageContext, (CGRect){ CGPointZero, imageViewSize }, tileImage); 
UIImage *finishedImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

imageView.image = finishedImage; 

Questo creerà un contesto un'immagine bitmap della dimensione desiderata, affiancare l'immagine in tale contesto, ottenere un UIImage fuori dal contesto, quindi assegnare al UIImageView. Puoi davvero inserire questo codice ovunque fintanto che la visualizzazione dell'immagine e l'immagine della tessera siano caricati e pronti per essere utilizzati.

2

Piuttosto che cercare di modificare un UIImageView, considerano sottoclasse UIView invece. UIImageView è progettato specificamente per un'immagine non affiancata e alcuni interni potrebbero rovinarti. Non è destinato a essere modificato nel modo in cui descrivi.

In una sottoclasse di UIView (UITiledImageView?) È possibile utilizzare il metodo drawRect: per fare ciò che si desidera. È anche possibile creare ivar per l'immagine, le sue dimensioni e le proprietà di piastrellatura per una maggiore flessibilità ed estensibilità.

Aggiornato con progetto di esempio: http://github.com/kailoa/6tringle-tiledimageview/tree/master

Il codice di disegno rilevanti:

- (void)drawRect:(CGRect)rect 
{ 
    if (TiledImage) { 

     //Since we are retaining the image, we append with ret_ref. this reminds us to release at a later date. 
     CGImageRef image_to_tile_ret_ref = CGImageRetain(TiledImage.CGImage); 

     CGRect image_rect; 
     image_rect.size = TiledImage.size; //This sets the tile to the native size of the image. Change this value to adjust the size of an indivitual "tile." 

     CGContextRef context = UIGraphicsGetCurrentContext(); 

     CGContextDrawTiledImage(context, image_rect, image_to_tile_ret_ref); 

     CGImageRelease(image_to_tile_ret_ref); 
    } 
} 
0

Recentemente ho fatto questo con la creazione di un UIView personalizzato.

@interface TiledImageView : UIView { 
@private 
    UIImage *image_; 
} 

@property (nonatomic, retain) UIImage *image; 
@end 

e per il file .m:

@implementation TiledImageView 
@synthesize image = image_; 

- (void)dealloc { 
    [image_ release]; 
    [super dealloc]; 
} 

- (id)initWithFrame:(CGRect)frame { 
    if (self = [super initWithFrame:frame]) { 
     // Initialization code 
     self.image = [UIImage imageNamed:@"BGTile.png"]; 

    } 
    return self; 
} 

- (void)drawRect:(CGRect)rect { 
    // Drawing code 
    CGImageRef image = CGImageRetain(image_.CGImage); 

    CGRect imageRect; 
    imageRect.origin = CGPointMake(0.0, 0.0); 
    imageRect.size = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image)); 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextClipToRect(context, CGRectMake(0.0, 0.0, rect.size.width, rect.size.height)); 
    CGContextDrawTiledImage(context, imageRect, image); 
    CGImageRelease(image); 
} 

@end 
26

Se si desidera solo per piastrelle un'immagine nella vista, cambiarlo in un UIView normale e piastrelle precedenti con UIColor initWithPatternImage:

backgroundView.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageWithContentsOfFile:[self bundlePath:@"some_tile_image.png" inDirectory:@"tiles"]]]; 
+2

vorrei usare - [UIImage imageNamed:] qui, ma sì, la stessa idea. Penso che sia possibile modificare anche l'offset, ma non ricordare esattamente. –

+1

Questo è perfetto. È piuttosto strano che iOS permetta a un'immagine di essere un UIColor, ma qualunque cosa. – jakeboxer

+16

Ciò provocherebbe perdite. Usa questo 'backgroundView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @" some_tile_image.png "]];' –

1

Ci scusiamo per non sapere come aggiungere commento di altre risposte, in modo da Ho creato una nuova risposta qui:

Voglio solo sottolineare la risposta fornita da Kailoa Kadano ha un bug, l'image_rect.origin non è inizializzato correttamente.

Circa 3 settimane fa, ho copiato il suo codice nel mio progetto e sembra funzionare. Tuttavia, ieri, ho provato a eseguire il codice in ios simulator (iPhone 4.3), è stato sospeso in CGContextDrawTiledImage. Dopo aver aggiunto la seguente riga come indicato nella risposta di keremk:

image_rect.origin = CGPointMake(0.0, 0.0); 

funziona di nuovo!

È piuttosto complicato, in realtà all'inizio ho provato con il simulatore iphone 4.3, quindi di recente l'ho provato con il simulatore iphone 4.0, poi ieri quando sono tornato al simulatore 4.3 o 4.2, il problema si verifica. Questo è il file image_rect.origin è indefinito, a volte è a zero, forse a volte ha dei dati casuali.

Problemi correlati