简体   繁体   English

获取 UIView 相对于其父视图的父视图的位置

[英]Get position of UIView in respect to its superview's superview

I have a UIView, in which I have arranged UIButtons.我有一个 UIView,我在其中安排了 UIButton。 I want to find the positions of those UIButtons.我想找到那些 UIButtons 的位置。

I am aware that buttons.frame will give me the positions, but it will give me positions only with respect to its immediate superview.我知道buttons.frame会给我职位,但它只会给我与其直接超级视图相关的职位。

Is there is any way we can find the positions of those buttons, withe respect to UIButtons superview's superview?关于 UIButtons 超级视图的超级视图,有什么方法可以找到这些按钮的位置吗?

For instance, suppose there is UIView named "firstView".例如,假设有一个名为“firstView”的 UIView。

Then, I have another UIView, "secondView".然后,我有另一个 UIView,“secondView”。 This "SecondView" is a subview of "firstView".这个“SecondView”是“firstView”的子视图。

Then I have UIButton as a subview on the "secondView".然后我将 UIButton 作为“secondView”上的子视图。

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

Now, is there any way we can find the position of that UIButton, with respect to "firstView"?现在,有什么方法可以找到那个 UIButton 相对于“firstView”的位置?

You can use this:你可以使用这个:

Objective-C Objective-C

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

Swift迅速

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

Documentation reference:文档参考:

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

Although not specific to the button in the hierarchy as asked I found this easier to visualize and understand:虽然不是特定于层次结构中的按钮,但我发现这更容易可视化和理解:

From here: original source从这里: 原始来源

在此处输入图像描述

ObjC:对象:

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

Swift:迅速:

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

Updated for Swift 3为 Swift 3 更新

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

        print(frame)
    }

在此处输入图像描述

UIView extension for converting subview's frame (inspired by @Rexb answer).用于转换子视图框架的 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: buttonView)

Frame: (X,Y,width,height).框架:(X,Y,宽度,高度)。

Hence width and height wont change even wrt the super-super view.因此,即使是超级超级视图,宽度和高度也不会改变。 You can easily get the X, Y as following.你可以很容易地得到X,Y如下。

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

If there are multiple views stacked and you don't need (or want) to know any possible views between the views you are interested in, you could do this:如果有多个视图堆叠并且您不需要(或不想)知道您感兴趣的视图之间的任何可能视图,您可以这样做:

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

where targetView would be the Button, baseView would be the ViewController.view .其中targetView将是 Button, baseView将是ViewController.view
What this function is trying to do is the following:这个函数试图做的是:
If targetView has no super view, it's current coordinate is returned.如果targetView没有超级视图,则返回它的当前坐标。
If targetView's super view is not the baseView (ie there are other views between the button and viewcontroller.view ), a converted coordinate is retrieved and passed to the next superview .如果targetView's超级视图不是superview (即按钮和viewcontroller.view之间还有其他视图),则检索转换后的坐标并将其传递给下一个超级视图。
It continues to do the same through the stack of views moving towards the baseView.它通过向 baseView 移动的视图堆栈继续执行相同的操作。
Once it reaches the baseView , it does one last conversion and returns it.一旦到达baseView ,它就会进行最后一次转换并返回它。
Note: it doesn't handle a situation where targetView is positioned under the baseView .注意:它不处理targetView位于baseView下的情况。

You can easily get the super-super view as following.您可以轻松获得超级超级视图,如下所示。

secondView -> [button superview] secondView -> [按钮超级视图]
firstView -> [[button superview] superview] firstView -> [[按钮超级视图] 超级视图]

Then, You can get the position of the button..然后,您可以获得按钮的位置..

You can use this:你可以使用这个:

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

Please note that the following code works regardless of how deep (nested) is the view you need the location for in the view hierarchy.请注意,无论您需要在视图层次结构中定位的视图有多深(嵌套),以下代码都有效。

Let's assume that you need the location of myView which is inside myViewsContainer and which is really deep in the view hierarchy, just follow the following sequence.假设您需要myView的位置,它位于myViewsContainer内部,并且在视图层次结构中非常深,只需按照以下顺序即可。

let myViewLocation = myViewsContainer.convert(myView.center, to: self.view)
  • myViewsContainer : the view container where the view you need the location for is located. myViewsContainer :您需要定位的视图所在的视图容器。

  • myView : the view you need the location for. myView :您需要位置的视图。

  • self.view : the main view self.view : 主视图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM