2012-06-14 5 views
34

Sembra che aspect fit allinea l'immagine alla parte inferiore del frame per impostazione predefinita. C'è un modo per ignorare l'allineamento mantenendo intatto aspect fit?UIImage aspect fit and align to top

** EDIT **

Questa domanda precede layout automatico. Infatti, il layout automatico è stato rivelato nel WWDC 2012 la stessa settimana in cui è stata posta questa domanda

+3

So che questo è vecchio ma questa soluzione è fantastica per le persone che trovano questo thread come ho fatto io: https://github.com/reydanro/UIImageViewAligned – tommybananas

risposta

21

In breve, non è possibile farlo con un UIImageView.

Una soluzione è creare una sottoclasse di UIView contenente uno UIImageView e modificarne la cornice in base alla dimensione dell'immagine. Ad esempio, è possibile trovare una versione here.

+0

Se è possibile ignorare UIImageView (come faccio sotto) puoi farlo in un colpo solo –

+1

Non proprio lo stesso effetto OP necessario. – Mundi

-2

Se è possibile eseguire la sottoclasse di UIImageView, è possibile ignorare la variabile image.

override var image: UIImage? { 
    didSet { 
     self.sizeToFit() 
    } 
} 

In Objective-C si può fare la stessa cosa ignorando il setter.

0

Il modo per fare ciò è modificare il contenuto Rect del livello UIImageView. Il seguente codice dal mio progetto (sottoclasse di UIImageView) presuppone scaleToFill e sposta l'immagine in modo tale che si allinea in alto, in basso, a sinistra o a destra invece dell'allineamento centrale predefinito. Per aspectFit sarebbe una soluzione simile.

typedef NS_OPTIONS(NSUInteger, AHTImageAlignmentMode) { 
    AHTImageAlignmentModeCenter = 0, 
    AHTImageAlignmentModeLeft = 1 << 0, 
    AHTImageAlignmentModeRight = 1 << 1, 
    AHTImageAlignmentModeTop = 1 << 2, 
    AHTImageAlignmentModeBottom = 1 << 3, 
    AHTImageAlignmentModeDefault = AHTImageAlignmentModeCenter, 
}; 

- (void)updateImageViewContentsRect { 
    CGRect imageViewContentsRect = CGRectMake(0, 0, 1, 1); 

    if (self.image.size.height > 0 && self.bounds.size.height > 0) { 

     CGRect imageViewBounds = self.bounds; 
     CGSize imageSize = self.image.size; 

     CGFloat imageViewFactor = imageViewBounds.size.width/imageViewBounds.size.height; 
     CGFloat imageFactor = imageSize.width/imageSize.height; 

     if (imageFactor > imageViewFactor) { 
      //Image is wider than the view, so height will match 
      CGFloat scaledImageWidth = imageViewBounds.size.height * imageFactor; 
      CGFloat xOffset = 0.0; 
      if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeLeft)) { 
       xOffset = -(scaledImageWidth - imageViewBounds.size.width)/2; 
      } else if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeRight)) { 
       xOffset = (scaledImageWidth - imageViewBounds.size.width)/2; 
      } 
      imageViewContentsRect.origin.x = (xOffset/scaledImageWidth); 
     } else if (imageFactor < imageViewFactor) { 
      CGFloat scaledImageHeight = imageViewBounds.size.width/imageFactor; 

      CGFloat yOffset = 0.0; 
      if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeTop)) { 
       yOffset = -(scaledImageHeight - imageViewBounds.size.height)/2; 
      } else if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeBottom)) { 
       yOffset = (scaledImageHeight - imageViewBounds.size.height)/2; 
      } 
      imageViewContentsRect.origin.y = (yOffset/scaledImageHeight); 
     } 
    } 
    self.layer.contentsRect = imageViewContentsRect; 
} 
0

Ho risolto questo nativamente in Interface Builder impostando un vincolo all'altezza del UIImageView, poiché l'immagine sarebbe sempre 'spinto' quando l'immagine era più grande della dimensione dello schermo.

In particolare, ho impostato UIImageView sulla stessa altezza della vista in cui si trova (tramite il vincolo di altezza), quindi ho posizionato UIImageView con i vincoli di spaziatura in IB. Ciò comporta che UIImageView ha un 'Aspect Fit' che rispetta ancora il vincolo di spaziatura superiore impostato in IB.

1

Ho avuto un problema simile. Il modo più semplice era creare una propria sottoclasse di UIImageView. Aggiungo per sottoclasse di 3 immobili in modo da ora può essere utilizzare facilmente senza conoscere implementazione interna:

@property (nonatomic) LDImageVerticalAlignment imageVerticalAlignment; 
@property (nonatomic) LDImageHorizontalAlignment imageHorizontalAlignment; 
@property (nonatomic) LDImageContentMode imageContentMode; 

potete verificare qui: https://github.com/LucasssD/LDAlignmentImageView

3

Basta impostare fondo la priorità di layout vincolo di ImageView al più basso (ad esempio 250) e farà il lavoro