iPhone - Get Position of UIView within entire UIWindow

IphoneCocoa TouchIosUiviewUiwindow

Iphone Problem Overview


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

Iphone Solutions


Solution 1 - Iphone

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...

  1. don't change when rotating the device.
  2. always have their origin in the top left corner of the unrotated screen.
  3. 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.

Solution 2 - Iphone

Swift 5+:

let globalPoint = aView.superview?.convert(aView.frame.origin, to: nil)

Solution 3 - Iphone

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

Solution 4 - Iphone

In Swift:

let globalPoint = aView.superview?.convertPoint(aView.frame.origin, toView: nil)

Solution 5 - Iphone

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

Solution 6 - Iphone

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

Solution 7 - Iphone

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)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionadamView Question on Stackoverflow
Solution 1 - IphoneNikolai RuheView Answer on Stackoverflow
Solution 2 - IphoneYuchenView Answer on Stackoverflow
Solution 3 - IphoneMohsenasmView Answer on Stackoverflow
Solution 4 - IphoneShlomi SchwartzView Answer on Stackoverflow
Solution 5 - IphoneAllan SpreysView Answer on Stackoverflow
Solution 6 - IphoneHugo JordaoView Answer on Stackoverflow
Solution 7 - IphoneLance SamariaView Answer on Stackoverflow