The position of a UIView
can obviously be determined by view.center
or view.frame
etc. but this only returns the position of the UIView
in relation to it's immediate superview.
I need to determine the position of the UIView
in the entire 320x480 co-ordinate system. For example, if the UIView
is in a UITableViewCell
it's position within the window could change dramatically irregardless of the superview.
Any ideas if and how this is possible?
Cheers :)
That's an easy one:
[aView convertPoint:localPosition toView:nil];
... converts a point in local coordinate space to window coordinates. You can use this method to calculate a view's origin in window space like this:
[aView.superview convertPoint:aView.frame.origin toView:nil];
2014 Edit: Looking at the popularity of Matt__C's comment it seems reasonable to point out that the coordinates...
don't change when rotating the device. always have their origin in the top left corner of the unrotated screen. are window coordinates: The coordinate system ist defined by the bounds of the window. The screen's and device coordinate systems are different and should not be mixed up with window coordinates.
Swift 5+:
let globalPoint = aView.superview?.convert(aView.frame.origin, to: nil)
Swift 3, with extension:
extension UIView{
var globalPoint :CGPoint? {
return self.superview?.convert(self.frame.origin, to: nil)
}
var globalFrame :CGRect? {
return self.superview?.convert(self.frame, to: nil)
}
}
In Swift:
let globalPoint = aView.superview?.convertPoint(aView.frame.origin, toView: nil)
Here is a combination of the answer by @Mohsenasm and a comment from @Ghigo adopted to Swift
extension UIView {
var globalFrame: CGRect? {
let rootView = UIApplication.shared.keyWindow?.rootViewController?.view
return self.superview?.convert(self.frame, to: rootView)
}
}
For me this code worked best:
private func getCoordinate(_ view: UIView) -> CGPoint {
var x = view.frame.origin.x
var y = view.frame.origin.y
var oldView = view
while let superView = oldView.superview {
x += superView.frame.origin.x
y += superView.frame.origin.y
if superView.next is UIViewController {
break //superView is the rootView of a UIViewController
}
oldView = superView
}
return CGPoint(x: x, y: y)
}
this worked for me
view.layoutIfNeeded() // this might be necessary depending on when you need to get the frame
guard let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else { return }
let frame = yourView.convert(yourView.bounds, to: keyWindow)
print("frame: ", frame)
Works well for me :)
extension UIView {
var globalFrame: CGRect {
return convert(bounds, to: window)
}
}
Success story sharing
aView.frame.origin
for me. It took me a whlie to realize my view's superview did not have a superview itself.[view.superview convertPoint:view.frame.origin toView:[UIApplication sharedApplication].keyWindow.rootViewController.view]