I am trying to use a Swift function to place a circle in the centre of a view so it is always on centre regardless of screen size. I can draw the circle at a point defined by a
Your screenCentre()
function won't work in viewDidLoad
because the view
is not yet sized to the screen, therefore its center is not in the middle of the screen.
Use this instead:
func screenCentre() -> CGPoint {
return CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.midY)
}
Note that I am using a CGPoint instead of a tuple, but the effect is the same. Also, the above function doesn't need to be in your view controller or any other class since it doesn't reference self
. It can be a global function.
Since Swift style guidelines encourage making methods over global functions, you might prefer to put the function in an extension like this:
extension UIScreen {
var centre: CGPoint {
return CGPoint(x: bounds.midX, y: bounds.midY)
}
}
Which can be called like this:
let centre = UIScreen.mainScreen().centre
print(centre)
First of all, UIViews have a center attribute, so you don't need to calculate it.
Second, the behavior may be inconsistent if changing it with viewDidLoad, and won't react to any changes to size/rotation.
I would recommend making a subClass of UIView that manages drawing the circle and doing something like this:
class ViewController: UIViewController {
var circle: CircleView?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
centerCircle()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
centerCircle()
}
func centerCircle() {
circle?.center = self.view.center
}
}
One thing you can do is use the _ to discard the return value from the function if you have no need for the value being return.
let _ = screenCentre()
Your screenCenter
function returns a tuple containing two CGFloat
values. These values are labeled x
and y
so you can access them by name when querying the function’s return value.
override func viewDidLoad() {
super.viewDidLoad()
let center = screenCentre()
//center.x contains the x value returned from screenCenter
//center.y contains the y value returned from screenCenter
circle(x: center.x , y: center.y)
}
In your ViewDidLoad method, you are only calling the method, but not storing the returned values. All you need to do to fix this is to create a variable and assign it to the call of your function.
Example:
let center = screenCentre()
print(center)
Now, the variable center will contain the coordinates of your screen's center. And in subsequent code, you can use center like you would with any other variable.