2014-10-13 18 views
12

Mam UIImageView, który pokazuje UIImage.UIImageView uzyskać pozycję pokazywania obrazu

Urządzenie UIImage może zmienić się na inne urządzenie UII o różnej wielkości, a pozycja i rozmiar obiektu UII wewnątrz ulegnie zmianie zgodnie z nim.

Mój problem polega na tym, że próbuję dodać widok, który będzie na końcu UIImage (który zmienia się przez cały czas) i wszystko, co mogę uzyskać, to ramka UIImageView (która cały czas pozostaje cały ekran).

Jak mogę uzyskać "ramkę" bieżącego pokazu UIImage?

+0

Nie ma bezpośredniego API, aby uzyskać te informacje. Musisz to obliczyć samodzielnie na podstawie ramki widoku obrazu, rozmiaru obrazu i "contentMode" widoku obrazu. – rmaddy

+0

@rmaddy to brzmi jak bardzo trudno powiedzieć. nie ma sposobu na zhackowanie go w prostszy sposób? –

+0

Możesz użyć Imageview.image.size.width/height, aby uzyskać witdth i wysokość. Chociaż nie wiem o właściwościach origin.x i y – Eyeball

Odpowiedz

17

Następujące będzie odpowiedzieć na pytanie, zakładając swoją UIImageView używany UIViewContentModeAspectFit:

Trzeba uważać rozmiaru obrazu obrazu wewnątrz UIImageView. To zależy od tego, jak ustawić contentMode. Zgodnie z twoim opisem zakładam, że używasz UIViewContentModeAspectFit. Wynikowy obraz będzie również wyśrodkowany w UIImageView, więc musisz również wziąć to pod uwagę w obliczeniach.

-(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); 
} 

Dla lepszego zobrazowania różnic pomiędzy trzema trybami treści, patrz poniżej:

enter image description here

+0

Czy to rozwiązanie nie przyjmuje "UIViewContentModeScaleAspectFit", a nie "UIViewContentModeScaleAspectFill"? Jeśli użyłeś 'UIViewContentModeScaleAspectFill', wtedy nie musisz obliczać. – rmaddy

+0

Dzięki, tak to jest ... Spójrz, oczywiście. Jednakże, jeśli ... potrzebujesz AslectFill, będziesz musiał wykonać pewne obliczenia, ponieważ obraz może zostać przycięty u góry lub z lewej strony, jeśli nie zmieści się w UIImageView bez zmiany stosunku wysokość/wysokość. Jest to różnica między ... AspectFill i ... ScaleToFill. – Marcus

+0

Świetnie, zadziałało dobrze – Sakthimuthiah

9

Dla 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 
} 

Dla Swift < 3,0

Oto powyższa metoda w Swift. Ponownie, zakładając, że contentMode jest ustawione na .ScaleAspectFit Jeśli nie ma obrazu na podanym imageViewCGRectZero zostanie zwrócony.

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

wielkie dzięki – fullMoon

4

Polecam używanie wbudowana funkcja AVMakeRectWithAspectRatio.

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

Parametry:

aspectRatio:
Szerokość i wysokość stosunek (proporcje), które chcesz zachować.

boundingRect: Prostokąt ograniczający, w który chcesz zmieścić.

Return Value Zwraca skalowany CGRect który utrzymuje proporcje określone przez aspectRatio który pasuje wewnątrz obwiedni Rect.

let boundingBox = AVMakeRectWithAspectRatioInsideRect (backgroundImage.Wielkość, ramka)

1

podstawie cudownie proste rozwiązanie z Januszem, oto co zrobiłem:

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