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

我有一个 UIView,其中我已经安排了 UIButtons。我想找到这些 UIButtons 的位置。

我知道,buttons.frame将给我的立场,但它将给我的立场,只有相对于其直接的监督。

有没有什么办法可以找到这些按钮的位置,根据 UIButtons 浏览器的视图?

例如,假设有一个名为“ firstView”的 UIView。

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

Then I have UIButton as a subview on the "secondView".

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

现在,有没有什么办法可以找到那个 UIButton 相对于“ firstView”的位置?

105515 次浏览

你可以用这个:

目标 C

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

斯威夫特

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

Documentation reference:

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

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

因此宽度和高度不会改变,甚至写超级视图。你可以很容易地得到 X,Y 如下。

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

更新为 Swift 3

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


print(frame)
}

enter image description here

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

从这里: original source

enter image description here

目的:

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

斯威夫特:

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

您可以像下面这样轻松地获得 super-super 视图。

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

然后,你可以得到按钮的位置. 。

你可以用这个:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.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)
}

其中 targetView是按钮,baseViewViewController.view
What this function is trying to do is the following:
如果 targetView没有超级视图,则返回它的当前坐标。
如果 targetView's超级视图不是 baseView (即在按钮和 viewcontroller.view之间存在其他视图) ,则检索转换后的坐标并将其传递给下一个 superview
It continues to do the same through the stack of views moving towards the baseView.
一旦到达 baseView,它执行最后一次转换并返回。
注意: 它不处理 targetView位于 baseView之下的情况。

用于转换子视图框架的 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)

Please note that the following code works regardless of how deep (nested) is the view you need the location for in the view hierarchy.

假设您需要 myView的位置,它位于 myViewsContainer内部,并且确实位于视图层次结构的深处,只需按照以下顺序。

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

  • MyView : 需要位置的视图。

  • self.view : the main view