Dapatkan posisi UIView sehubungan dengan superview-nya

97

Saya memiliki UIView, di mana saya telah mengatur UIButtons. Saya ingin mencari posisi tombol-tombol tersebut.

Saya sadar itu buttons.frameakan memberi saya posisi, tetapi itu akan memberi saya posisi hanya sehubungan dengan superview langsungnya.

Adakah cara untuk menemukan posisi tombol-tombol tersebut, sehubungan dengan superview UIButtons superview?

Misalnya, ada UIView bernama "firstView".

Lalu, saya punya UIView lain, "secondView". "SecondView" ini adalah subview dari "firstView".

Lalu saya memiliki UIButton sebagai subview di "secondView".

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

Sekarang, adakah cara kita dapat menemukan posisi UIButton itu, sehubungan dengan "firstView"?

Shailesh
sumber

Jawaban:

192

Anda dapat menggunakan ini:

Objective-C

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

Cepat

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

Referensi dokumentasi:

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

mprivat.dll
sumber
Untuk menambahkan ini, jika tampilan Anda tidak selalu dalam tampilan yang sama (katakanlah, jika Anda menggunakan ini dalam sebuah fungsi) Anda dapat meletakkan '... fromView: [button superview]];'
mylogon
39

Meskipun tidak spesifik untuk tombol dalam hierarki seperti yang diminta, saya merasa ini lebih mudah untuk divisualisasikan dan dipahami:

Dari sini: sumber asli

masukkan deskripsi gambar di sini

ObjC:

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

Cepat:

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

Diperbarui untuk Swift 3

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

        print(frame)
    }

masukkan deskripsi gambar di sini

iAj
sumber
7

Bingkai: (X, Y, lebar, tinggi).

Karenanya lebar dan tinggi tidak akan berubah bahkan dengan tampilan super-super. Anda bisa dengan mudah mendapatkan X, Y sebagai berikut.

X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;
iRavi iVooda
sumber
Tetapi mengapa saya mendapatkan nilai X, Y dalam jumlah yang sangat tinggi seperti ketika X saya adalah 0,0 maka saya mendapatkan dengan baris kode Anda sebagai; 180224 atau lebih?
5

Jika ada beberapa tampilan yang ditumpuk dan Anda tidak perlu (atau ingin) mengetahui kemungkinan tampilan di antara tampilan yang Anda minati, Anda dapat melakukan ini:

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

di mana targetViewakan menjadi Tombol, baseViewakan menjadi ViewController.view.
Apa yang coba dilakukan fungsi ini adalah sebagai berikut:
Jika targetViewtidak memiliki tampilan super, koordinat saat ini dikembalikan.
Jika targetView'stampilan super bukan baseView (yaitu ada tampilan lain di antara tombol dan viewcontroller.view), koordinat yang diubah diambil dan diteruskan ke yang berikutnya superview.
Ini terus melakukan hal yang sama melalui tumpukan tampilan yang bergerak menuju baseView.
Setelah mencapai baseView, itu melakukan satu konversi terakhir dan mengembalikannya.
Catatan: itu tidak menangani situasi di mana targetViewdiposisikan di bawah baseView.

Rexb
sumber
4

Ekstensi UIView untuk mengubah bingkai subview (terinspirasi oleh jawaban @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
sumber
2

Anda dapat dengan mudah mendapatkan tampilan super-super sebagai berikut.

secondView -> [tombol
superview ] firstView -> [[tombol superview] superview]

Kemudian, Anda bisa mendapatkan posisi tombol ..

Anda dapat menggunakan ini:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.y;
kata altintop
sumber
2
Menambahkan beberapa penjelasan akan membuat jawaban ini lebih berguna.
Sagar Zala