Erhalten Sie die Position von UIView in Bezug auf die Übersicht seiner Übersicht

97

Ich habe eine UIView, in der ich UIButtons arrangiert habe. Ich möchte die Positionen dieser UIButtons finden.

Ich bin mir bewusst, buttons.framedass ich die Positionen erhalten werde, aber es gibt mir Positionen nur in Bezug auf die unmittelbare Aufsicht.

Gibt es eine Möglichkeit, die Positionen dieser Schaltflächen in Bezug auf die Übersicht von UIButtons zu finden?

Angenommen, es gibt UIView mit dem Namen "firstView".

Dann habe ich eine andere UIView, "secondView". Diese "SecondView" ist eine Unteransicht von "firstView".

Dann habe ich UIButton als Unteransicht auf der "secondView".

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

Gibt es eine Möglichkeit, die Position dieses UIButton in Bezug auf "firstView" zu finden?

Shailesh
quelle

Antworten:

192

Sie können dies verwenden:

Ziel c

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

Schnell

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

Dokumentationsreferenz:

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

mprivat
quelle
Wenn sich Ihre Ansicht nicht immer in derselben Ansicht befindet (z. B. wenn Sie diese in einer Funktion verwenden), können Sie '... fromView: [button supiew]];'
Mylonon
39

Obwohl nicht spezifisch für die Schaltfläche in der Hierarchie, wie gefragt, fand ich dies einfacher zu visualisieren und zu verstehen:

Von hier: Originalquelle

Geben Sie hier die Bildbeschreibung ein

Objekt:

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

Schnell:

let point = subview1.convert(subview2.frame.origin, to: viewControll.view)
Vlad
quelle
20

Aktualisiert für Swift 3

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

        print(frame)
    }

Geben Sie hier die Bildbeschreibung ein

iAj
quelle
7

Rahmen: (X, Y, Breite, Höhe).

Daher ändern sich Breite und Höhe auch in der Super-Super-Ansicht nicht. Sie können das X, Y wie folgt leicht erhalten.

X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;
iRavi iVooda
quelle
Aber warum ich den X, Y-Wert in so hoher Menge bekomme, wie wenn mein X 0,0 war, dann bekomme ich mit Ihren Codezeilen als; 180224 oder so?
5

Wenn mehrere Ansichten gestapelt sind und Sie keine möglichen Ansichten zwischen den Ansichten kennen möchten (oder möchten), können Sie Folgendes tun:

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

Wo targetViewwäre der Knopf, baseViewwäre der ViewController.view.
Diese Funktion versucht Folgendes:
Wenn targetViewkeine Superansicht vorhanden ist, wird die aktuelle Koordinate zurückgegeben.
Wenn targetView'sdie Superansicht nicht die Basisansicht ist (dh zwischen der Schaltfläche und befinden sich andere Ansichten viewcontroller.view), wird eine konvertierte Koordinate abgerufen und an die nächste übergeben superview.
Dies wird auch weiterhin durch den Stapel von Ansichten durchgeführt, die sich in Richtung baseView bewegen.
Sobald es das erreicht baseView, führt es eine letzte Konvertierung durch und gibt sie zurück.
Hinweis: Es wird keine Situation behandelt, in der targetViewsich unter der Position befindet baseView.

Rexb
quelle
4

UIView-Erweiterung zum Konvertieren des Frames der Unteransicht (inspiriert von der @ Rexb-Antwort).

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
quelle
2

Sie können die Super-Super-Ansicht wie folgt erhalten.

secondView -> [Schaltflächenübersicht]
firstView -> [[Schaltflächenübersicht] Übersicht]

Dann können Sie die Position der Schaltfläche erhalten.

Sie können dies verwenden:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.y;
sagte altintop
quelle
2
Das Hinzufügen einer Erklärung würde diese Antwort nützlicher machen.
Sagar Zala