Ios 如何更改以编程方式创建的按钮的约束?

Ios 如何更改以编程方式创建的按钮的约束?,ios,swift2,constraints,Ios,Swift2,Constraints,我想使用编程创建的约束将编程创建的按钮移动到该按钮。但是我遇到了几个错误。我可以对一个按钮执行此操作,该按钮是非编程创建的,约束也是非编程创建的。代码如下: var displayLink: CADisplayLink? var startTime: CFAbsoluteTime? let duration = 2.0 @IBOutlet var TopConstraintforMoving1: NSLayoutConstraint! @IBAction func Startbutton(s

我想使用编程创建的约束将编程创建的按钮移动到该按钮。但是我遇到了几个错误。我可以对一个按钮执行此操作,该按钮是非编程创建的,约束也是非编程创建的。代码如下:

var displayLink: CADisplayLink?
var startTime: CFAbsoluteTime?
let duration = 2.0
@IBOutlet var TopConstraintforMoving1: NSLayoutConstraint!  
@IBAction func Startbutton(sender: UIButton) {
    startDisplayLink()
}
func startDisplayLink() {
    displayLink?.invalidate()
    startTime = CFAbsoluteTimeGetCurrent()
    displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:")
    displayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
func handleDisplayLink(displayLink: CADisplayLink) {
    let elapsed = CFAbsoluteTimeGetCurrent() - startTime!
    var percentComplete = CGFloat(elapsed / duration)
    if percentComplete >= 1.0 {
        percentComplete = 1.0
        stopDisplayLink()
    }
    TopConstraintforMoving1.constant = 390 - 350 * percentComplete
}
let button = UIButton()
var displayLink: CADisplayLink?
var startTime: CFAbsoluteTime?
let duration = 2.0
var topConstraint: NSLayoutConstraint!
@IBAction func start(sender: UIButton) {
    displayLink?.invalidate()
    startTime = CFAbsoluteTimeGetCurrent()
    displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:")
    displayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
}
func handleDisplayLink(displayLink: CADisplayLink) {
    button.hidden = false
    let elapsed = CFAbsoluteTimeGetCurrent() - startTime!
    var percentComplete = CGFloat(elapsed / duration)
    if percentComplete >= 1.0 {
        percentComplete = 1.0
        displayLink.invalidate()
        button.hidden = true
    }
    topConstraint.constant = 393 - 350 * percentComplete
    NSLayoutConstraint.activateConstraints([
        button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 122),
        topConstraint,
        button.widthAnchor.constraintEqualToConstant(75),
        button.heightAnchor.constraintEqualToConstant(75)
        ])
}
func buttonPressed(sender: UIButton!) {
    button.hidden = true
    displayLink?.invalidate()
}
override func viewDidLoad() {
    super.viewDidLoad()
    button.hidden = true
    button.setImage(UIImage(named: "BlueBall.png")!, forState: UIControlState.Normal)
    button.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false
    topConstraint = button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 393)  
    NSLayoutConstraint.activateConstraints([
        button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 122),
        topConstraint,
        button.widthAnchor.constraintEqualToConstant(75),
        button.heightAnchor.constraintEqualToConstant(75)
        ])   
}
这是我用编程方式创建的按钮的代码:

var startTime: CFAbsoluteTime?
let duration = 2.0
let button = UIButton(type: UIButtonType.System) as UIButton
var topConstraintforMoving1: NSLayoutConstraint?  
@IBAction func StartButton(sender: UIButton) {
    startTime = CFAbsoluteTimeGetCurrent()
    let elapsed = CFAbsoluteTimeGetCurrent() - startTime!
    var percentComplete = CGFloat(elapsed / duration)
    if percentComplete >= 1.0 {
        percentComplete = 1.0
    }
    button.setImage(UIImage(named: "BlueBall.png")!, forState: UIControlState.Normal)
    button.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
    view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false      
    topConstraintforMoving1 = button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 390 - 350 * percentComplete)  
    NSLayoutConstraint.activateConstraints([
        button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 122),
        button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 393),
        button.widthAnchor.constraintEqualToConstant(75),
        button.heightAnchor.constraintEqualToConstant(75),
        ])      
} 
按钮不动了。
请帮忙,谢谢。安东

你在正确的轨道上。在代码中创建按钮的代码中,也在代码中创建约束。但是,您没有保存指向该约束的指针

(函数
constraintEqualToAnchor
的返回类型为NSLayoutConstraint,但您不会将该返回值保存在任何位置。)

创建实例变量并将约束保存到该变量。如果愿意,甚至可以将约束标记为IBOutlet

然后像处理在IB(Interface Builder)中创建的按钮一样,操纵约束的常量值

编辑: 您的代码可能如下所示:

TopConstraintforMoving1 = 
  button.topAnchor.constraintEqualToAnchor(
    view.topAnchor, 
    constant: 390 - 350 * percentComplete)
请注意,变量名应该以小写字母开头,因此实际上应该是:

topConstraintforMoving1 = 
  button.topAnchor.constraintEqualToAnchor(
    view.topAnchor, 
    constant: 390 - 350 * percentComplete)

我尝试以不同的方式构建它,但使用了相同的方法,它成功了。代码如下:

var displayLink: CADisplayLink?
var startTime: CFAbsoluteTime?
let duration = 2.0
@IBOutlet var TopConstraintforMoving1: NSLayoutConstraint!  
@IBAction func Startbutton(sender: UIButton) {
    startDisplayLink()
}
func startDisplayLink() {
    displayLink?.invalidate()
    startTime = CFAbsoluteTimeGetCurrent()
    displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:")
    displayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
func handleDisplayLink(displayLink: CADisplayLink) {
    let elapsed = CFAbsoluteTimeGetCurrent() - startTime!
    var percentComplete = CGFloat(elapsed / duration)
    if percentComplete >= 1.0 {
        percentComplete = 1.0
        stopDisplayLink()
    }
    TopConstraintforMoving1.constant = 390 - 350 * percentComplete
}
let button = UIButton()
var displayLink: CADisplayLink?
var startTime: CFAbsoluteTime?
let duration = 2.0
var topConstraint: NSLayoutConstraint!
@IBAction func start(sender: UIButton) {
    displayLink?.invalidate()
    startTime = CFAbsoluteTimeGetCurrent()
    displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:")
    displayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
}
func handleDisplayLink(displayLink: CADisplayLink) {
    button.hidden = false
    let elapsed = CFAbsoluteTimeGetCurrent() - startTime!
    var percentComplete = CGFloat(elapsed / duration)
    if percentComplete >= 1.0 {
        percentComplete = 1.0
        displayLink.invalidate()
        button.hidden = true
    }
    topConstraint.constant = 393 - 350 * percentComplete
    NSLayoutConstraint.activateConstraints([
        button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 122),
        topConstraint,
        button.widthAnchor.constraintEqualToConstant(75),
        button.heightAnchor.constraintEqualToConstant(75)
        ])
}
func buttonPressed(sender: UIButton!) {
    button.hidden = true
    displayLink?.invalidate()
}
override func viewDidLoad() {
    super.viewDidLoad()
    button.hidden = true
    button.setImage(UIImage(named: "BlueBall.png")!, forState: UIControlState.Normal)
    button.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false
    topConstraint = button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 393)  
    NSLayoutConstraint.activateConstraints([
        button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 122),
        topConstraint,
        button.widthAnchor.constraintEqualToConstant(75),
        button.heightAnchor.constraintEqualToConstant(75)
        ])   
}

如何将实例保存到约束?您的意思是如何将约束保存到实例变量?请参阅对我答案的编辑。因此,要创建topConstraintforMoving1,我必须执行以下操作:var topConstraintforMoving1=NSLaysoutConstraint()?否。您需要var
var topConstraintforMoving1:NSLaysoutConstraint
。您不应该在变量声明中创建NSLaysoutConstraint的实例,因为它永远不会被使用。谢谢。现在在顶部(class(name):UIViewController{//code}),它说:class(name)没有初始值设定项btw,不建议使用CADisplayLink并在每个帧上手动更改约束的常量。最好使用UIVIEW动画,比如动画动画:动画:在那里你改变了约束,并调用动画块内的LayuthIdvices。Ya,但是我不能点击动画中间的按钮“Ya,但是我不能点击动画中间的按钮”“是的,你可以。”也许你问一下会更好@matt我正在阅读您关于UIButton动画的评论,我同意您关于使用UIVIew动画块的说法,但我目前在UIWebView中面临类似的问题。当webView设置动画时,它变得不可触摸,并且无法将触摸事件转发到webView内容。您建议如何使用CADisplayLink更改约束?“您建议如何使用CADisplayLink更改约束”相同答案。我不会的。