Süpervizörün süpervizör görüşüne göre UIView konumunu alın


101

UIButton'larını düzenlediğim bir UIView'ım var. Bu UIButtonlarının konumlarını bulmak istiyorum.

Bunun buttons.framebana pozisyonları vereceğinin farkındayım , ancak bana yalnızca anlık denetimiyle ilgili pozisyonlar verecek.

Bu düğmelerin konumlarını UIButtons süpervizörünün süpervizörüne göre bulmamızın bir yolu var mı?

Örneğin, "firstView" adında bir UIView olduğunu varsayalım.

Ardından, başka bir UIView, "secondView" var. Bu "SecondView", "firstView" ın bir alt görünümüdür.

Sonra "secondView" üzerinde bir alt görünüm olarak UIButton var.

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

Şimdi, bu UIButton'un "firstView" a göre konumunu bulmamızın bir yolu var mı?

Yanıtlar:



44

Hiyerarşideki düğmeye özel olmasa da sorulduğu gibi bunu görselleştirmeyi ve anlamayı daha kolay buldum:

Buradan: orijinal kaynak

görüntü açıklamasını buraya girin

ObjC:

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

Swift:

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

21

Swift 3 için güncellendi

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

        print(frame)
    }

görüntü açıklamasını buraya girin


7

Çerçeve: (X, Y, genişlik, yükseklik).

Bu nedenle, genişlik ve yükseklik süper süper görünümde bile değişmeyecek. X, Y'yi aşağıdaki gibi kolayca alabilirsiniz.

X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;

Ama neden X, Y değerini X'im 0,0 olduğu zamanki gibi bu kadar yüksek miktarda alıyorum, o zaman kod satırlarınızla şu şekilde alıyorum; 180224 ya da öylesine?

5

Birden fazla görünüm yığılmışsa ve ilgilendiğiniz görünümler arasındaki olası görünümleri bilmenize gerek yoksa (veya istemiyorsanız), şunu yapabilirsiniz:

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

nerede targetViewDüğme olurdu baseViewolurdu ViewController.view.
Bu işlevin yapmaya çalıştığı şey şudur: Süper görünümü
yoksa targetView, mevcut koordinatı döndürülür.
Eğer targetView'ssüper görünümü (düğme ve arasındaki diğer görünümler vardır yani baseView değil viewcontroller.view), bir alınan ve bir sonraki geçirilir koordinat dönüştürülmüş superview.
BaseView'a doğru hareket eden görünüm yığınları aracılığıyla aynı şeyi yapmaya devam eder.
Adresine ulaştığında, baseViewson bir dönüştürme yapar ve onu döndürür.
Not: targetViewaltında konumlandırılan bir durumu işlemez baseView.


4

Alt görünümün çerçevesini dönüştürmek için UIView uzantısı (@Rexb yanıtından esinlenilmiştir).

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)

3

Süper süper görünümü aşağıdaki gibi kolayca elde edebilirsiniz.

secondView -> [düğme
denetleme ] ilk Görünüm -> [[düğme denetleme ] denetleme]

Ardından, düğmenin konumunu alabilirsiniz ..

Bunu kullanabilirsiniz:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.y;

2
Bazı açıklamalar eklemek bu cevabı daha kullanışlı hale getirecektir.
Sagar Zala

0

Lütfen aşağıdaki kodun, görünüm hiyerarşisinde konuma ihtiyacınız olan görünümün ne kadar derin (iç içe geçmiş) olduğuna bakılmaksızın çalıştığını unutmayın.

myViewİçeride myViewsContainerolan ve görünüm hiyerarşisinde gerçekten derin olan konumuna ihtiyacınız olduğunu varsayalım , aşağıdaki sırayı takip edin.

let myViewLocation = myViewsContainer.convert(myView.center, to: self.view)
  • myViewsContainer : konumu ihtiyacınız olan görünümün bulunduğu görünüm kapsayıcısı.

  • myView : konuma ihtiyaç duyduğunuz görünüm.

  • self.view : ana görünüm

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.