72

I've looked at a dozen SO questions on this topic, and none of the answers have worked for me. Maybe this will help get me back on the right path.

Imagine this setup:

enter image description here

I want to get the center coordinates of the UIButton relative to the UIView.

In other words, the UIButton center may be 215, 80 within the UITableViewCell, but relative to the UIView they should be more like 260, 165. How do I convert between the two?

Here's what I've tried:

[[self.view superview] convertPoint:button.center fromView:button];  // fail
[button convertPoint:button.center toView:self.view];  // fail
[button convertPoint:button.center toView:nil];  // fail
[button convertPoint:button.center toView:[[UIApplication sharedApplication] keyWindow]];  // fail

I could do it the hard way by looping through all of the button's superviews and adding up the x and y coordinates, but I suspect that's overkill. I just need to find the right combination of covertPoint settings. Right?

Axeva
  • 4,277
  • 5
  • 36
  • 61
  • It will help if you add the following to your question: The frames of all 4 views in your image, the output you get from the methods you have tried, and the value you actually want. – rmaddy Apr 08 '13 at 15:43

5 Answers5

136

button.center is the center specified within the coordinate system of its superview, so I assume that the following works:

CGPoint p = [button.superview convertPoint:button.center toView:self.view]

Or you compute the button's center in its own coordinate system and use that:

CGPoint buttonCenter = CGPointMake(button.bounds.origin.x + button.bounds.size.width/2,
                                   button.bounds.origin.y + button.bounds.size.height/2);
CGPoint p = [button convertPoint:buttonCenter toView:self.view];

Swift 4+

let p = button.superview!.convert(button.center, to: self.view)

// or

let buttonCenter = CGPoint(x: button.bounds.midX, y: button.bounds.midY)
let p = button.convert(buttonCenter, to: self.view)
Martin R
  • 488,667
  • 78
  • 1,132
  • 1,248
  • 3
    Bingo! Your first attempt was what I was looking for. The center being tied to the coordinate system of the superview is what I was missing. Thank you! – Axeva Apr 08 '13 at 16:10
  • Thanks @Martin R . This was helpful – Chamath Jeevan Apr 26 '16 at 17:13
  • 2
    **Swift 3:** `var buttonCenter = CGPoint(x: button.bounds.origin.x + button.bounds.size.width / 2, y: button.bounds.origin.y + button.bounds.size.height / 2) var p = button.convertPoint(buttonCenter, to: self.view) ` – Matt Butler Nov 08 '16 at 01:50
  • So the Swift 4 version is missing the `.superview?` , right? – de. Mar 18 '21 at 09:42
  • 1
    @de.: You are right! Hopefully correct now. – Martin R Mar 19 '21 at 21:42
17

Swift 5.2

You need to call convert from the button, not the superview. In my case I needed width data so I converted the bounds instead of just center point. The code below works for me:

let buttonAbsoluteFrame = button.convert(button.bounds, to: self.view)
Trev14
  • 2,516
  • 2
  • 22
  • 31
  • Naming Frame is confusing, because frame.origin of bounds is zero. Why do you call convert if you just can button.bounds to get width. If you really need to get relative coordinate of a view, then use convert(button.frame ....) – Almas Adilbek Jun 20 '19 at 13:16
14

Martin answer is correct. For developers using Swift, you can get the position of an object (button, view,...) relative to the screen by using:

var p = obj.convertPoint(obj.center, toView: self.view)

println(p.x)  // this prints the x coordinate of 'obj' relative to the screen
println(p.y)  // this prints the y coordinate of 'obj' relative to the screen
rsc
  • 9,304
  • 4
  • 32
  • 31
  • 1
    @Axeva there is also a `convertRect` for more precise calculation [Here](http://stackoverflow.com/a/33879565/1634890) – Juan Boero Nov 23 '15 at 20:11
9

Here is Swift 3 update of @Pablo's answer, which off course worked great in my case.

if let window = UIApplication.shared.keyWindow {
    parent.convert(child.frame.origin, to: window)
}
AamirR
  • 9,385
  • 3
  • 47
  • 59
1

in swift 2.2 worked for me:

var OrignTxtNomeCliente:CGPoint!

if let orign = TXT_NomeCliente.superview, let win = UIApplication.sharedApplication().keyWindow {
        OrignTxtNomeCliente = orign.convertPoint(TXT_NomeCliente.frame.origin, toView: win)
    }
Pablo Ruan
  • 1,553
  • 1
  • 15
  • 12