2011-08-29 18 views
11

Ho un [UIButton buttonWithType:UIButtonTypeCustom] che ha un'immagine (o un'immagine di sfondo - lo stesso problema) creata da [UIImage imageWithContentsOfFile:] che punta a un file JPG preso dalla fotocamera e salvato nella cartella documenti dall'applicazione.UIButton problema di rotazione dell'immagine

Se si definisce solo l'immagine per UIControlStateNormal, quando si tocca il pulsante l'immagine diventa più scura come previsto, ma ruota anche di 90 gradi o di 180 gradi. Quando rimuovo il dito ritorna alla normalità.

Ciò non accade se uso la stessa immagine per UIControlStateHighlighted, ma poi perdo l'indicazione di tocco (immagine più scura).

Ciò si verifica solo con un'immagine letta da un file. Non succede con [UIImage ImageNamed:].

Ho provato a salvare il file in formato PNG anziché come JPG. In questo caso l'immagine si presenta con l'orientamento sbagliato all'inizio e non viene ruotata di nuovo quando viene toccata. Questa non è comunque una buona soluzione perché il PNG è troppo grande e lento da gestire.

È un errore o sto facendo qualcosa di sbagliato?

+2

Ho un problema simile in cui dopo aver impostato lo sfondo sbottonare immagine di una foto selezionata da un fotoritocco, l'immagine appare ruotata di 90 gradi. – marciokoko

risposta

4

Non sono riuscito a trovare una soluzione adeguata e ho avuto bisogno di una soluzione rapida. Di seguito è una funzione che, data una UIImage, restituisce una nuova immagine che viene oscurata con un riempimento alfa scuro. I comandi di riempimento contesto potrebbero essere sostituiti con altre routine di disegno o riempimento per fornire diversi tipi di oscuramento.

Questo non è ottimizzato ed è stato realizzato con una conoscenza minima della api grafica.

È possibile utilizzare questa funzione per impostare l'immagine dello stato di UIControlStateHighlight in modo che almeno risulti più scura.

+ (UIImage *)darkenedImageWithImage:(UIImage *)sourceImage 
{ 
    UIImage * darkenedImage = nil; 

    if (sourceImage) 
    { 
     // drawing prep 
     CGImageRef source = sourceImage.CGImage; 
     CGRect drawRect = CGRectMake(0.f, 
            0.f, 
            sourceImage.size.width, 
            sourceImage.size.height); 
     CGContextRef context = CGBitmapContextCreate(NULL, 
                drawRect.size.width, 
                drawRect.size.height, 
                CGImageGetBitsPerComponent(source), 
                CGImageGetBytesPerRow(source), 
                CGImageGetColorSpace(source), 
                CGImageGetBitmapInfo(source) 
                ); 

     // draw given image and then darken fill it 
     CGContextDrawImage(context, drawRect, source); 
     CGContextSetBlendMode(context, kCGBlendModeOverlay); 
     CGContextSetRGBFillColor(context, 0.f, 0.f, 0.f, 0.5f); 
     CGContextFillRect(context, drawRect); 

     // get context result 
     CGImageRef darkened = CGBitmapContextCreateImage(context); 
     CGContextRelease(context); 

     // convert to UIImage and preserve original orientation 
     darkenedImage = [UIImage imageWithCGImage:darkened 
                 scale:1.f 
               orientation:sourceImage.imageOrientation]; 
     CGImageRelease(darkened); 
    } 

    return darkenedImage; 
} 
2

Per risolvere questo problema è necessario funzione di normalizzazione aggiuntiva in questo modo:

public extension UIImage { 

    func normalizedImage() -> UIImage! { 

     if self.imageOrientation == .Up { 
      return self 
     } 

     UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) 
     self.drawInRect(CGRectMake(0, 0, self.size.width, self.size.height)) 
     let normalized = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     return normalized 
    } 
} 

allora si può usare in quel modo:

self.photoButton.sd_setImageWithURL(avatarURL, 
forState: .Normal, 
placeholderImage: UIImage(named: "user_avatar_placeholder")) { 

    [weak self] (image, error, cacheType, url) in 

    guard let strongSelf = self else { 

     return 
    } 

    strongSelf.photoButton.setImage(image.normalizedImage(), forState: .Normal 
} 
Problemi correlati