以编程方式移动按钮不起作用 - 快速

时间:2022-06-21 22:44:49

I'm having trouble programatically moving a button.

我以编程方式移动按钮时遇到了麻烦。

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

我在viewDidLoad中使用此代码,我不使用自动布局:

    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.

但是在屏幕上按钮保持在45。

Any idea what I'm doing wrong?

知道我做错了什么吗?

3 个解决方案

#1


6  

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

在viewDidAppear方法中更改按钮位置,它将在运行时更改它的位置,您的代码将是:

override func viewDidAppear(animated: Bool) {

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

From this post: Difference between viewDidLoad and viewDidAppear

从这篇文章:viewDidLoad和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.

当视图控制器首次加载到内存中时,viewDidLoad只调用一次。这是您希望实例化任何实例变量并构建在此视图控制器的整个生命周期中存在的任何视图的位置。但是,此时通常尚未显示该视图。

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.

viewDidAppear在视图实际可见时被调用,并且可以在视图控制器的生命周期中多次调用(例如,当模式视图控制器被关闭并且视图再次可见时)。您可以在此处执行任何布局操作或在UI中执行任何绘图 - 例如,呈现模态视图控制器。

#2


0  

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.

编辑:我建议这样做的原因是,我认为button.frame返回按钮的框架矩形的副本,因此您不是直接更改原始CGRect实例的原始子属性,这就是不反映更改的原因。

#3


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.

好吧,我想UIView子类只能监听-setFrame:setter(当谈论-frame属性时);改变它的子值,即使是非对象(因此不能超载-size和-origin属性上的setter反应),也不会立即产生IMO效果。

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

在这种情况下,您必须通过另一个变量修改框架并通过-setFrame将其设置回来:正如其他帖子所示。

#1


6  

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

在viewDidAppear方法中更改按钮位置,它将在运行时更改它的位置,您的代码将是:

override func viewDidAppear(animated: Bool) {

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

From this post: Difference between viewDidLoad and viewDidAppear

从这篇文章:viewDidLoad和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.

当视图控制器首次加载到内存中时,viewDidLoad只调用一次。这是您希望实例化任何实例变量并构建在此视图控制器的整个生命周期中存在的任何视图的位置。但是,此时通常尚未显示该视图。

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.

viewDidAppear在视图实际可见时被调用,并且可以在视图控制器的生命周期中多次调用(例如,当模式视图控制器被关闭并且视图再次可见时)。您可以在此处执行任何布局操作或在UI中执行任何绘图 - 例如,呈现模态视图控制器。

#2


0  

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.

编辑:我建议这样做的原因是,我认为button.frame返回按钮的框架矩形的副本,因此您不是直接更改原始CGRect实例的原始子属性,这就是不反映更改的原因。

#3


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.

好吧,我想UIView子类只能监听-setFrame:setter(当谈论-frame属性时);改变它的子值,即使是非对象(因此不能超载-size和-origin属性上的setter反应),也不会立即产生IMO效果。

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

在这种情况下,您必须通过另一个变量修改框架并通过-setFrame将其设置回来:正如其他帖子所示。