2014-10-13 11 views
12

Ho un UIImageView che mostra un UIImage.UIImageView ottenere la posizione della rappresentazione Immagine

L'immagine di UII può passare ad un'altra immagine UII di dimensioni diverse, e la posizione e la dimensione della UIImmagine all'interno cambierà in base ad essa.

Il mio problema è che sto provando ad aggiungere una vista che sarà alla fine della UIImage (che cambia tutto il tempo) e tutto quello che posso ottenere è il frame di UIImageView (che rimane a schermo intero tutto il tempo).

Come posso ottenere il "fotogramma" di corrente che mostra UIImmagine?

+0

Non c'è API diretto per ottenere queste informazioni. Dovrai calcolarlo da solo sulla base della cornice della vista dell'immagine, della dimensione dell'immagine e del 'contentMode' della vista dell'immagine. – rmaddy

+0

@rmaddy che sembra una cosa molto difficile da dire. non c'è un modo per hackerarlo in un modo più semplice? –

+0

È possibile utilizzare Imageview.image.size.width/height per ottenere l'altezza e l'altezza. Anche se non conosco le proprietà origin.x e y – Eyeball

risposta

17

Di seguito vi rispondere alla tua domanda, supponendo che l'UIImageView UIViewContentModeAspectFit usato:

si deve considerare il dimensionamento immagine dell'immagine all'interno UIImageView. Questo dipende da come si imposta il contentMode. Secondo la tua descrizione, presumo tu stia utilizzando UIViewContentModeAspectFit. Anche l'immagine risultante verrà centrata in UIImageView, quindi devi tenerne conto anche per il calcolo.

-(CGRect)calculateClientRectOfImageInUIImageView:(UIImageView *)imgView 
{ 
    CGSize imgViewSize=imgView.frame.size;     // Size of UIImageView 
    CGSize imgSize=imgView.image.size;      // Size of the image, currently displayed 

    // Calculate the aspect, assuming imgView.contentMode==UIViewContentModeScaleAspectFit 

    CGFloat scaleW = imgViewSize.width/imgSize.width; 
    CGFloat scaleH = imgViewSize.height/imgSize.height; 
    CGFloat aspect=fmin(scaleW, scaleH); 

    CGRect imageRect={ {0,0} , { imgSize.width*=aspect, imgSize.height*=aspect } }; 

    // Note: the above is the same as : 
    // CGRect imageRect=CGRectMake(0,0,imgSize.width*=aspect,imgSize.height*=aspect) I just like this notation better 

    // Center image 

    imageRect.origin.x=(imgViewSize.width-imageRect.size.width)/2; 
    imageRect.origin.y=(imgViewSize.height-imageRect.size.height)/2; 

    // Add imageView offset 

    imageRect.origin.x+=imgView.frame.origin.x; 
    imageRect.origin.y+=imgView.frame.origin.y; 

    return(imageRect); 
} 

Per una migliore spiegazione delle differenze tra le tre modalità di contenuto, vedi sotto:

enter image description here

+0

Questa soluzione non presuppone 'UIViewContentModeScaleAspectFit' e non' UIViewContentModeScaleAspectFill'? Se hai usato 'UIViewContentModeScaleAspectFill', non è necessario alcun calcolo. – rmaddy

+0

Grazie, sì è .. Adatta naturalmente. Tuttavia, se ... AslectFill è necessario, dovrai anche eseguire alcuni calcoli poiché l'immagine potrebbe essere ritagliata in alto oa sinistra nel caso in cui non si adatti a UIImageView senza modificare il rapporto con/altezza. Questa è la differenza tra ... AspectFill e ... ScaleToFill. – Marcus

+0

Ottimo, ha funzionato bene per me – Sakthimuthiah

9

per SWIFT 3,0

// MARK: - Create Rect 
func calculateRectOfImageInImageView(imageView: UIImageView) -> CGRect { 
    let imageViewSize = imageView.frame.size 
    let imgSize = imageView.image?.size 

    guard let imageSize = imgSize, imgSize != nil else { 
     return CGRect.zero 
    } 

    let scaleWidth = imageViewSize.width/imageSize.width 
    let scaleHeight = imageViewSize.height/imageSize.height 
    let aspect = fmin(scaleWidth, scaleHeight) 

    var imageRect = CGRect(x: 0, y: 0, width: imageSize.width * aspect, height: imageSize.height * aspect) 
    // Center image 
    imageRect.origin.x = (imageViewSize.width - imageRect.size.width)/2 
    imageRect.origin.y = (imageViewSize.height - imageRect.size.height)/2 

    // Add imageView offset 
    imageRect.origin.x += imageView.frame.origin.x 
    imageRect.origin.y += imageView.frame.origin.y 

    return imageRect 
} 

per SWIFT < 3.0

Ecco il metodo sopra in Swift. Anche in questo caso, supponendo che contentMode sia impostato su .ScaleAspectFit Se non ci sono immagini sullo imageViewCGRectZero restituito.

func calculateRectOfImageInImageView(imageView: UIImageView) -> CGRect { 
    let imageViewSize = imageView.frame.size 
    let imgSize = imageView.image?.size 

    guard let imageSize = imgSize where imgSize != nil else { 
     return CGRectZero 
    } 

    let scaleWidth = imageViewSize.width/imageSize.width 
    let scaleHeight = imageViewSize.height/imageSize.height 
    let aspect = fmin(scaleWidth, scaleHeight) 

    var imageRect = CGRect(x: 0, y: 0, width: imageSize.width * aspect, height: imageSize.height * aspect) 
    // Center image 
    imageRect.origin.x = (imageViewSize.width - imageRect.size.width)/2 
    imageRect.origin.y = (imageViewSize.height - imageRect.size.height)/2 

    // Add imageView offset 
    imageRect.origin.x += imageView.frame.origin.x 
    imageRect.origin.y += imageView.frame.origin.y 

    return imageRect 
} 
+0

grazie mille – fullMoon

4

Si consiglia di utilizzare la funzione incorporata AVMakeRectWithAspectRatio.

func AVMakeRectWithAspectRatioInsideRect(_ aspectRatio: CGSize, _ boundingRect: CGRect) -> CGRect 

Parametri:

aspectRatio:
La larghezza e l'altezza rapporto (aspect ratio) che si desidera mantenere.

boundingRect: Il rettangolo di delimitazione che si desidera inserire.

Valore di ritorno Restituisce un CGRect scala che mantiene le proporzioni specificato da aspectRatio che si inserisce all'interno di delimitazione Rect.

let boundingBox = AVMakeRectWithAspectRatioInsideRect (backgroundImage.dimensioni, frame)

1

Basato sul meravigliosamente soluzione semplice da Janusz, ecco quello che ho fatto:

let visibleRect = AVMakeRect(aspectRatio: CGSize(width: image.size.width, height: image.size.height), insideRect: self.frame) 
if visibleRect.contains(point) { 
    // Do something great here... 
}