수퍼 뷰의 수퍼 뷰와 관련하여 UIView의 위치를 ​​가져옵니다.


97

UIButtons를 정렬 한 UIView가 있습니다. 해당 UIButton의 위치를 ​​찾고 싶습니다.

나는 buttons.frame그것이 나에게 위치를 줄 것이라는 것을 알고 있지만 그것은 즉각적인 감독에 대해서만 나에게 위치를 줄 것입니다.

UIButtons superview의 superview와 관련하여 해당 버튼의 위치를 ​​찾을 수있는 방법이 있습니까?

예를 들어 "firstView"라는 이름의 UIView가 있다고 가정합니다.

그런 다음 다른 UIView, "secondView"가 있습니다. 이 "SecondView"는 "firstView"의 하위보기입니다.

그런 다음 "secondView"에 대한 하위보기로 UIButton이 있습니다.

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

이제 "firstView"와 관련하여 해당 UIButton의 위치를 ​​찾을 수있는 방법이 있습니까?

답변:


192

이것을 사용할 수 있습니다 :

목표 -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

39

요청한대로 계층 구조의 버튼에 국한되지는 않지만 시각화하고 이해하기가 더 쉽다는 것을 알았습니다.

여기에서 : 원본 소스

여기에 이미지 설명 입력

ObjC :

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

빠른:

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

20

Swift 3 업데이트

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

        print(frame)
    }

여기에 이미지 설명 입력


7

프레임 : (X, Y, 너비, 높이).

따라서 너비와 높이는 슈퍼 슈퍼 뷰에서도 변경되지 않습니다. 다음과 같이 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), a는 검색하고 다음에 전달되는 좌표 변환 superview.
baseView로 이동하는 뷰 스택을 통해 동일한 작업을 계속합니다.
에 도달하면 baseView마지막 변환을 한 번 수행하고 반환합니다.
참고 :이 상황을 처리하지 않습니다 targetView세 이하 위치를 baseView.


4

하위 뷰의 프레임을 변환하기위한 UIView 확장 (@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

다음과 같이 쉽게 슈퍼 슈퍼 뷰를 얻을 수 있습니다.

secondView-> [버튼 수퍼 뷰]
firstView-> [[버튼 수퍼 뷰] 수퍼 뷰]

그러면 버튼의 위치를 ​​알 수 있습니다.

이것을 사용할 수 있습니다 :

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

2
설명을 추가하면이 답변이 더 유용해질 것입니다.
Sagar Zala
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.