Uzyskaj pozycję UIView w odniesieniu do superviewu jego superviewu

99

Mam UIView, w którym ułożyłem UIButtons. Chcę znaleźć pozycje tych przycisków UIB.

Zdaję sobie sprawę, że buttons.frameda mi to pozycje, ale da mi pozycje tylko w odniesieniu do bezpośredniego superwizji.

Czy jest jakiś sposób, abyśmy mogli znaleźć pozycje tych przycisków, z poszanowaniem superviewu UIButtons?

Na przykład załóżmy, że istnieje UIView o nazwie „firstView”.

Następnie mam inny UIView, „secondView”. Ten „SecondView” jest podziałem widoku „firstView”.

Następnie mam UIButton jako podwidok na „secondView”.

->UIViewController.view
--->FirstView A
------->SecondView B
------------>Button

Czy jest jakiś sposób, abyśmy mogli znaleźć pozycję tego UIButton w odniesieniu do „firstView”?

Shailesh
źródło

Odpowiedzi:

196

Możesz użyć tego:

Cel C

CGRect frame = [firstView convertRect:buttons.frame fromView:secondView];

Szybki

let frame = firstView.convert(buttons.frame, from:secondView)

Odnośnik do dokumentacji:

https://developer.apple.com/documentation/uikit/uiview/1622498-convert

mprivat
źródło
Aby dodać do tego, jeśli twój widok nie zawsze jest w tym samym widoku (powiedzmy, jeśli używasz tego w funkcji), możesz wstawić '... fromView: [button superview]];'
mylogon
41

Chociaż nie jest to specyficzne dla przycisku w hierarchii, zgodnie z pytaniem, łatwiej to wizualizować i zrozumieć:

Stąd: oryginalne źródło

wprowadź opis obrazu tutaj

CelC:

CGPoint point = [subview1 convertPoint:subview2.frame.origin toView:viewController.view];

Szybki:

let point = subview1.convert(subview2.frame.origin, to: viewControll.view)
Vlad
źródło
21

Zaktualizowano dla Swift 3

    if let frame = yourViewName.superview?.convert(yourViewName.frame, to: nil) {

        print(frame)
    }

wprowadź opis obrazu tutaj

iAj
źródło
7

Rama: (X, Y, szerokość, wysokość).

Stąd szerokość i wysokość nie zmienią się nawet w super-super widoku. Możesz łatwo uzyskać X, Y w następujący sposób.

X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;
iRavi iVooda
źródło
Ale dlaczego otrzymuję wartość X, Y w tak dużej ilości, jak wtedy, gdy mój X wynosił 0,0, wtedy otrzymuję z twoimi liniami kodu jako; 180224 lub tak?
5

Jeśli istnieje wiele widoków nałożonych na siebie i nie potrzebujesz (lub nie chcesz) znać żadnych możliwych widoków między widokami, które Cię interesują, możesz to zrobić:

static func getConvertedPoint(_ targetView: UIView, baseView: UIView)->CGPoint{
    var pnt = targetView.frame.origin
    if nil == targetView.superview{
        return pnt
    }
    var superView = targetView.superview
    while superView != baseView{
        pnt = superView!.convert(pnt, to: superView!.superview)
        if nil == superView!.superview{
            break
        }else{
            superView = superView!.superview
        }
    }
    return superView!.convert(pnt, to: baseView)
}

gdzie targetViewbyłby przycisk, baseViewbyłoby ViewController.view.
Ta funkcja próbuje wykonać następujące czynności:
Jeśli targetViewnie ma super widoku, zwracana jest aktualna współrzędna.
Jeśli targetView'ssuper widok nie jest widokiem baseView (tj. Między przyciskiem a znajdują się inne widoki viewcontroller.view), przekonwertowana współrzędna jest pobierana i przekazywana do następnego superview.
Nadal robi to samo przez stos widoków przesuwających się w kierunku baseView.
Gdy osiągnie baseView, wykonuje ostatnią konwersję i zwraca ją.
Uwaga: nie obsługuje sytuacji, w której targetViewjest umieszczony pod baseView.

Rexb
źródło
4

Rozszerzenie UIView do konwersji ramki subview (inspirowane odpowiedzią @Rexb).

extension UIView {

    // there can be other views between `subview` and `self`
    func getConvertedFrame(fromSubview subview: UIView) -> CGRect? {
        // check if `subview` is a subview of self
        guard subview.isDescendant(of: self) else {
            return nil
        }

        var frame = subview.frame
        if subview.superview == nil {
            return frame
        }

        var superview = subview.superview
        while superview != self {
            frame = superview!.convert(frame, to: superview!.superview)
            if superview!.superview == nil {
                break
            } else {
                superview = superview!.superview
            }
        }

        return superview!.convert(frame, to: self)
    }

}

// usage:
let frame = firstView.getConvertedFrame(fromSubview: buttons.frame)
boro
źródło
2

Możesz łatwo uzyskać super-super widok w następujący sposób.

secondView -> [button
superview ] firstView -> [[button superview ] superview]

Następnie możesz uzyskać położenie przycisku.

Możesz użyć tego:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.y;
powiedział altintop
źródło
2
Dodanie jakiegoś wyjaśnienia uczyniłoby tę odpowiedź bardziej użyteczną.
Sagar Zala,