รับตำแหน่งของ UIView ตามมุมมองที่ยอดเยี่ยมของ superview


101

ฉันมี UIView ซึ่งฉันได้จัดเรียง UIButtons ฉันต้องการค้นหาตำแหน่งของ UIButtons เหล่านั้น

ฉันรู้ว่าbuttons.frameจะให้ตำแหน่งแก่ฉัน แต่มันจะทำให้ฉันได้ตำแหน่งเฉพาะในส่วนที่เกี่ยวกับมุมมองสูงสุดในทันที

มีวิธีใดบ้างที่เราสามารถค้นหาตำแหน่งของปุ่มเหล่านั้นด้วยความเคารพต่อ superview ของ UIButtons superview?

ตัวอย่างเช่นสมมติว่ามี UIView ชื่อ "firstView"

จากนั้นฉันก็มี UIView "secondView" อีกอัน "SecondView" นี้เป็นมุมมองย่อยของ "firstView"

จากนั้นฉันก็มี UIButton เป็นมุมมองย่อยใน "secondView"

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

ตอนนี้มีวิธีใดบ้างที่เราสามารถค้นหาตำแหน่งของ UIButton นั้นเกี่ยวกับ "firstView" ได้หรือไม่?

คำตอบ:


198

คุณสามารถใช้สิ่งนี้:

วัตถุประสงค์ -C

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

รวดเร็ว

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

เอกสารอ้างอิง:

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


หากต้องการเพิ่มสิ่งนี้หากมุมมองของคุณไม่ได้อยู่ในมุมมองเดียวกันเสมอไป (เช่นหากคุณใช้สิ่งนี้ในฟังก์ชัน) คุณสามารถใส่ "... fromView: [button superview]];"
mylogon

44

แม้ว่าจะไม่เฉพาะเจาะจงกับปุ่มในลำดับชั้นตามที่ถามฉันพบว่าสิ่งนี้ง่ายกว่าในการมองเห็นและเข้าใจ:

จากที่นี่: แหล่งที่มาดั้งเดิม

ป้อนคำอธิบายภาพที่นี่

ObjC:

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

รวดเร็ว:

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

21

อัปเดตสำหรับ Swift 3

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

        print(frame)
    }

ป้อนคำอธิบายภาพที่นี่


7

กรอบ: (X, Y, กว้าง, สูง)

ดังนั้นความกว้างและความสูงจะไม่เปลี่ยนแปลงแม้กระทั่งมุมมอง super-super คุณสามารถรับ X, Y ได้อย่างง่ายดายดังต่อไปนี้

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

แต่ทำไมฉันถึงได้ค่า X, Y ในจำนวนที่สูงเช่นเมื่อ X ของฉันเป็น 0,0 ฉันจึงได้รับบรรทัดโค้ดของคุณเป็น; 180224 หรือเปล่า?

5

หากมีหลายมุมมองซ้อนกันและคุณไม่ต้องการ (หรือต้องการ) รู้มุมมองที่เป็นไปได้ระหว่างมุมมองที่คุณสนใจคุณสามารถทำได้:

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

targetViewปุ่มจะอยู่ที่ไหนจะbaseViewเป็นไฟล์ViewController.view.
สิ่งที่ฟังก์ชันนี้พยายามทำมีดังต่อไปนี้:
หากtargetViewไม่มีมุมมองขั้นสูงจะส่งคืนพิกัดปัจจุบัน
ถ้าtargetView'sมุมมองสุดไม่ได้เป็น baseView (เช่นมีมุมมองอื่น ๆ ระหว่างปุ่มviewcontroller.view) superviewซึ่งเป็นแปลงพิกัดที่ถูกดึงมาและผ่านไปยัง
มันยังคงทำเช่นเดียวกันผ่านกลุ่มมุมมองที่เคลื่อนไปยัง baseView
เมื่อถึงจุดbaseViewนั้นจะทำการแปลงครั้งสุดท้ายและส่งกลับ
หมายเหตุ: มันไม่ได้จัดการกับสถานการณ์ที่targetViewอยู่ในตำแหน่งbaseView.


4

ส่วนขยาย UIView สำหรับการแปลงเฟรมของ subview (แรงบันดาลใจจากคำตอบ @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)

3

คุณสามารถรับมุมมองที่ยอดเยี่ยมได้อย่างง่ายดายดังต่อไปนี้

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

จากนั้นคุณจะได้รับตำแหน่งของปุ่ม ..

คุณสามารถใช้สิ่งนี้:

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

2
การเพิ่มคำอธิบายจะทำให้คำตอบนี้มีประโยชน์มากขึ้น
Sagar Zala

0

โปรดทราบว่าโค้ดต่อไปนี้ใช้งานได้ไม่ว่ามุมมอง (ซ้อน) จะลึกเพียงใดในมุมมองที่คุณต้องการตำแหน่งในลำดับชั้นของมุมมอง

สมมติว่าคุณต้องการตำแหน่งmyViewที่อยู่ด้านในmyViewsContainerและอยู่ลึกลงไปในลำดับชั้นของมุมมองเพียงทำตามลำดับต่อไปนี้

let myViewLocation = myViewsContainer.convert(myView.center, to: self.view)
  • myViewsContainer : คอนเทนเนอร์มุมมองที่มุมมองที่คุณต้องการตำแหน่งตั้งอยู่

  • myView : มุมมองที่คุณต้องการสำหรับตำแหน่ง

  • self.view : มุมมองหลัก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.