Nhận vị trí của UIView so với superview của nó


97

Tôi có một UIView, trong đó tôi đã sắp xếp các UIButtons. Tôi muốn tìm vị trí của các UIButtons đó.

Tôi biết rằng điều đó buttons.framesẽ mang lại cho tôi các vị trí, nhưng nó sẽ chỉ cho tôi các vị trí đối với tầm nhìn trực tiếp của nó.

Có cách nào để chúng tôi có thể tìm thấy vị trí của các nút đó, liên quan đến superview của UIButtons superview không?

Ví dụ: giả sử có UIView có tên "firstView".

Sau đó, tôi có một UIView khác, "secondView". "SecondView" này là một lượt xem phụ của "firstView".

Sau đó, tôi có UIButton làm chế độ xem phụ trên "chế độ xem thứ hai".

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

Bây giờ, có cách nào chúng ta có thể tìm thấy vị trí của UIButton đó, liên quan đến "firstView" không?

Câu trả lời:


192

Bạn có thể sử dụng cái này:

Objective-C

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

Nhanh

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

Tài liệu tham khảo:

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


Để thêm vào điều này, nếu chế độ xem của bạn không phải lúc nào cũng ở cùng chế độ xem (giả sử, nếu bạn đang sử dụng chế độ này trong một hàm), bạn có thể đặt '... fromView: [button superview]];'
mylogon

39

Mặc dù không cụ thể cho nút trong hệ thống phân cấp như đã hỏi, tôi thấy điều này dễ hình dung và dễ hiểu hơn:

Từ đây: nguồn gốc

nhập mô tả hình ảnh ở đây

Mục tiêuC:

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

Nhanh:

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

20

Đã cập nhật cho Swift 3

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

        print(frame)
    }

nhập mô tả hình ảnh ở đây


7

Khung: (X, Y, width, height).

Do đó, chiều rộng và chiều cao sẽ không thay đổi ngay cả khi chế độ xem siêu siêu. Bạn có thể dễ dàng lấy X, Y như sau.

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

Nhưng tại sao tôi nhận được giá trị X, Y với số lượng quá cao như khi X của tôi là 0,0 thì tôi nhận được các dòng mã của bạn là; 180224 hay lâu hơn?

5

Nếu có nhiều chế độ xem xếp chồng lên nhau và bạn không cần (hoặc muốn) biết bất kỳ chế độ xem nào có thể có giữa các chế độ xem mà bạn quan tâm, bạn có thể thực hiện điều này:

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

đâu targetViewsẽ là Nút, baseViewsẽ là ViewController.view.
Những gì hàm này đang cố gắng thực hiện như sau:
Nếu targetViewkhông có chế độ xem siêu cấp, tọa độ hiện tại của nó được trả về.
Nếu targetView'ssiêu chế độ xem không phải là chế độ xem cơ sở (tức là có các chế độ xem khác giữa nút và viewcontroller.view), một tọa độ đã chuyển đổi sẽ được truy xuất và chuyển cho tiếp theo superview.
Nó tiếp tục làm như vậy thông qua chồng các chế độ xem di chuyển về phía baseView.
Khi nó đạt đến baseView, nó thực hiện một chuyển đổi cuối cùng và trả về nó.
Lưu ý: nó không xử lý một tình huống targetViewđược định vị dưới baseView.


4

Tiện ích mở rộng UIView để chuyển đổi khung của lượt xem phụ (lấy cảm hứng từ câu trả lời @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)

2

Bạn có thể dễ dàng có được chế độ xem siêu siêu khủng như sau.

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

Sau đó, bạn có thể nhận được vị trí của nút ..

Bạn có thể sử dụng cái này:

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

2
Thêm một số giải thích sẽ làm cho câu trả lời này hữu ích hơn.
Sagar Zala
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.