2010-04-22 12 views
14

Byłem zaskoczony, aby nie znaleźć odpowiedź na to pytanie, być może jest to coś bardzo prosty jakoś przeoczyć:Get rozmiaru UIView po zastosowaniu CGAffineTransform

Jak uzyskać prawdziwe rozmiaru UIView po tym, jak zastosować CGAffineTransform do to?

np.

moje UIView ma rozmiar 300 x 200, stosuję przeliczanie skalowania, powiedzmy, czynnik 2, zarówno poziomy, jak i pionowy, więc UIView teraz zajmuje 600 x 400 na ekranie, ale to granice i jego granice wciąż powracają do rozmiaru 300 x 200 ... gdzie mogę znaleźć rzeczywisty rozmiar UIView?

ps. zapomniałem wspomnieć, że chcę również obrócić uiview. Jeśli zastosuję tylko skalowanie, CGSizeApplyAffineTransform działa świetnie, ale gdy jest również obrót, to nie działa poprawnie.

Edit: drawnonward wskazał mnie we właściwym kierunku, po prostu dopracowane nieco kod do kompilowania i tutaj jest:

UIView* view = (your view being transformed); 
CGAffineTransform trans = (view.transform or create a new transformation); 

CGRect rect = [view bounds]; 
CGMutablePathRef path = CGPathCreateMutable(); 
rect.origin = CGPointZero; 
CGPathAddRect(path , &trans , rect); 
rect = CGPathGetBoundingBox(path); 
CGPathRelease(path); 

Teraz rect.size zawiera wymiary widoku z transformacji zastosowano Jeszcze raz dziękuję za ciągnienie

Odpowiedz

11

[myView frame] zwraca ramkę widoku w widoku nadrzędnym dla układu i względnych rozmiarów. [myView bounds] przywraca granice widoku jako widoczne dla siebie, do rysowania. Jeśli masz transformacje zastosowane do wielu widoków, możesz użyć convertRect: do lub z widoku.

Edytuj:

Może coś takiego.

CGRect rect = [view bounds]; 
CGPathRef path = CGPathCreateMutable(); 
rect.origin = CGPointZero; 
CGPathAddRect(rect , [view transform]); 
rect = CGPathGetBoundingBox(path); 
CGPathRelease(path); 

Użycie [view center] do znalezienia pozycji w superwizji.

+1

Oto dokumentacja dotycząca "ramki" z dokumentacji Apple: Ostrzeżenie: Jeśli właściwość transform nie jest przekształceniem tożsamości, wartość tej właściwości jest niezdefiniowana i dlatego być zignorowanym. Tak więc ramka nie wchodzi w grę, gdy stosuje się transformację. I "granice" zwraca zawsze pierwotny rozmiar –

+0

Rzeczywiście! Argh, ta biblioteka funkcji, o której zawsze zapominam - CGPathGetBoundingBox to była sztuczka. Edytowałem to pytanie za pomocą działającego kodu, bardzo dziękuję człowiekowi –

+0

Należy również zauważyć, że właściwość centrum ma działać, nawet z przekształceniami bez tożsamości. – Olie

2

Użyj CGSizeApplyAffineTransform(size, transform) i zwróci transformowany rozmiar. Istnieją również podobne funkcje CGPoint i .

+0

To nie działa poprawnie, gdy CGSizeApplyAffineTransform zawiera również obrót, ale poza tym masz rację w przypadkach, w których zastosowano tylko skalowanie. (mój błąd nie zawierał również rotacji w moim pytaniu) –

2

Prostsze: widok z (granice) Powierzchnia S, które przekształcają tr Applied otrzymanej wielkości:

CGSizeMake(s.width*hypotf(tr.a, tr.b), s.height*hypotf(tr.c, tr.d)) 

Jednakże, jeśli Superview View lub dowolny widok przodek zawiera dowolny niż jednostka transformacji stosowana, wielkość nie ma sensu w kategoriach absolutnych.

Jeśli chcesz bezwzględny rozmiar widoku we współrzędnych okna po dowolnej arbitralnej transformacji zastosowanej do tego widoku lub jego superwizytów, powinieneś najpierw obliczyć absolutną macierz transformacji, tworząc całą transformację widoku aż do okna głównego, a następnie zastosować powyższy wzór do wyniku.

33

używam:

CGRect transformedBounds = CGRectApplyAffineTransform(view.bounds, view.transform); 
+0

Wierzę, że właśnie "view.bounds" będzie lepszą odpowiedzią. dlaczego zmieniasz granice tutaj, zamiast tylko przyjmować rozmiar ramy? –

0

Ale zastosować obrotowy przekształcać, to nie dostają odpowiedniej wielkości przez CGPathGetBoundingBox.

2

Stare pytanie, ale wpadł tutaj, po poszukiwaniu rozwiązania i ton prób.To było proste;

view.layer.frame ma wszystkie zastosowane przekształcenia, a otrzymasz rozmiar od view.layer.frame.size łatwo.

- poniżej tu nie ma odpowiedzi na to pytanie - -

A dla mojego problemu, starałem się obliczyć nową wartość center po zmianie layer.anchorPoint mojego widoku obróconym, więc to nie rusza . I w końcu tak to zrobiło;

CGPoint topLeft = [self.superview convertPoint:CGPointMake(0, 0) fromView:self]; 
self.layer.anchorPoint = CGPointMake(0, 0); 
self.center = topLeft; 

do odwrotnej

CGPoint center = [self.superview convertPoint:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) fromView:self]; 
self.layer.anchorPoint = CGPointMake(.5, .5); 
self.center = center; 

końcu.

Powiązane problemy