获得UIView关于其superview的超级视图的位置

时间:2013-07-10 13:46:23

标签: iphone ios uiview uibutton cgrect

我有一个UIView,我在其中安排了UIButtons。我想找到那些UIButton的位置。

我知道buttons.frame会给我这些职位,但只会就其直接的超级视图给我立场。

对于UIButton superview的超级视图,我们是否有办法找到这些按钮的位置?

例如,假设UIView名为“firstView”。

然后,我有另一个UIView,“secondView”。这个“SecondView”是“firstView”的子视图。

然后我将UIButton作为“secondView”的子视图。

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

现在,有没有什么方法可以找到UIButton的位置,就“firstView”而言?

8 个答案:

答案 0 :(得分:154)

您可以使用:

目标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

答案 1 :(得分:16)

针对Swift 3进行了更新

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

        print(frame)
    }

enter image description here

答案 2 :(得分:16)

虽然不是特定于层次结构中的按钮,但我发现这更容易想象和理解:

从这里开始:original source

enter image description here

ObjC:

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

夫特:

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

答案 3 :(得分:6)

框架:( X,Y,宽度,高度)。

因此即使在超级超视图下,宽度和高度也不会改变。您可以轻松获得X,Y如下。

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

答案 4 :(得分:2)

您可以轻松获得以下超级超级视图。

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

然后,您可以获取按钮的位置。

您可以使用此:

const requiredText = (
  <React.Fragment>
    <p>This isn't rendering</p>
    <p>and I'm not sure why</p>
  </React.Fragment>
);

答案 5 :(得分:1)

如果堆叠了多个视图,并且您不需要(或不想)知道您感兴趣的视图之间的任何可能的视图,则可以这样做:

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是按钮,baseViewViewController.view
该函数要执行的操作如下:
如果targetView没有超级视图,则返回其当前坐标。
如果targetView's超级视图不是baseView(即按钮和viewcontroller.view之间还有其他视图),则检索转换后的坐标并将其传递到下一个superview
在移向baseView的视图堆栈中,它继续执行相同的操作。
一旦到达baseView,它就会进行最后一次转换并返回。
注意:targetView放在baseView下的情况无法解决。

答案 6 :(得分:0)

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)

答案 7 :(得分:0)

请注意,无论您在视图层次结构中需要的位置视图的深度(嵌套)有多深,以下代码均有效。

让我们假设您需要myViewmyViewsContainer内并且确实在视图层次结构中很深的位置,只需遵循以下顺序即可。

let myViewLocation = myViewsContainer.convert(myView.center, to: self.view)
  • myViewsContainer :您需要该位置的视图所在的视图容器。

  • myView :您需要位置的视图。

  • self.view :主视图