4

I'm having trouble programmatically moving a button.

I am using this code in viewDidLoad and I am NOT using auto-layout:

    button.frame.origin = CGPoint(x: 0, y: 0)

But the button remains in its original position on the screen at runtime.

The strange thing is, the coordinates are actually being updated, but not being represented on the screen.

If I run the following code:

    print(button.frame.origin.x)  // prints 45.0
    button.frame.origin = CGPoint(x: 0, y: 0)
    print(button.frame.origin.x)  // prints 0.0

But on screen the button remains at 45.

What am I doing wrong?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Bingo
  • 375
  • 6
  • 17

3 Answers3

7

Change your button position in viewDidAppear method and it will change it's position at run time and your code will be:

override func viewDidAppear(animated: Bool) {

    button.frame.origin = CGPoint(x: 0, y: 0)
}

From this post: Difference between viewDidLoad and viewDidAppear

viewDidLoad is called exactly once, when the view controller is first loaded into memory. This is where you want to instantiate any instance variables and build any views that live for the entire lifecycle of this view controller. However, the view is usually not yet visible at this point.

viewDidAppear is called when the view is actually visible, and can be called multiple times during the lifecycle of a View Controller (for instance, when a Modal View Controller is dismissed and the view becomes visible again). This is where you want to perform any layout actions or do any drawing in the UI - for example, presenting a modal view controller.

Community
  • 1
  • 1
Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
  • Makes sense, but what I cannot understand is why does prepositioning a button not work from viewDidLoad but changing its background does? for example: button.backgroundColor = UIColor.blackColor() works but button.frame.origin = CGPoint(x: 0, y: 0) doesn't. – Bingo Sep 24 '15 at 05:33
  • 1
    @Bingo In the view controller's view did load x and y position is just begun to set. in view will appear we getting perfect location of the button so you can move the button's position. – Ashish Kakkad Sep 24 '15 at 05:41
  • can you also change the position outside viewdid appear – Cing Feb 04 '16 at 22:28
1

Perhaps a long shot (?), but...

Instead of:

button.frame.origin = CGPoint(x: 0, y: 0)

Try:

var frame = button.frame
frame.origin = CGPoint(x: 0, y: 0)
button.frame = frame

EDIT: The reason I suggest this is, I think button.frame returns a copy of the button's frame rect, so you are not directly changing the origin sub-property of the original CGRect instance, and that is why the change is not reflected.

Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
0

Well, I guess that UIView subclasses listen on -setFrame: setter only (when talking around -frame property); changing the its sub-value, which is even non-object (and thus cannot overload setters on -size and -origin attributes to react), won't have any immediate effect IMO.

In that case, you have to modify the frame via another variable and set it back via -setFrame: as other posts suggest.

Michi
  • 1,464
  • 12
  • 15