Get position of UIView in respect to its superview's superview
I have a UIView, in which I have arranged UIButtons. I want to find the positions of those 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.
Is there is any way we can find the positions of those buttons, withe respect to UIButtons superview's superview?
For instance, suppose there is UIView named "firstView".
Then, I have another UIView, "secondView". This "SecondView" is a subview of "firstView".
Then I have UIButton as a subview on the "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"?
You can use this:
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
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
if let frame = yourViewName.superview?.convert(yourViewName.frame, to: nil) {
print(frame)
}
UIView extension for converting subview's frame (inspired by @Rexb answer).
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).
Hence width and height wont change even wrt the super-super view. You can easily get the X, Y as following.
X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;