【问题标题】:Auto Layout center UIView above another UIView at its center自动布局中心 UIView 在其中心的另一个 UIView 之上
【发布时间】:2015-11-15 13:25:53
【问题描述】:

我有一个UIView (popup) 和多个UIButtons (sender)。如果我触摸sender,我想将popup 置于sender 的坐标处。

但是,从自动布局开始,popup 总是在刷新时移回初始位置。我知道我必须使用约束并以编程方式更改它们。

不幸的是,我不知道如何使用约束来调整下面的代码。尤其是popup 比sender 大。

谁能给我一些建议,告诉我如何在启用自动布局的情况下将UIViews 中心移动到发件人的中心?谢谢!!

这是显示问题的以下代码的屏幕图像:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var number: UIImageView!
    @IBOutlet weak var popup: UIView!

    @IBAction func openPopup(sender: UIButton) {
        self.popup.center = sender.center
        //old position: (190.5, 124.0) - new Position: (173.0, 414.0)
    }

    @IBAction func updateImage(sender: UIButton) {
        self.number.image = UIImage(named: "img-1")
    }
}

这是我到目前为止所拥有的,但我不知道这是否正确以及我必须使用什么类型的NSLayoutConstraint 来实现这一点:

import UIKit

class ViewController: UIViewController {

    var id = 1
    @IBOutlet weak var number: UIImageView!
    @IBOutlet weak var popup: UIView!

    @IBOutlet weak var popupy: NSLayoutConstraint!
    @IBOutlet weak var popupx: NSLayoutConstraint!

    @IBAction func openPopup(sender: UIButton) {

    popupx.constant = reposition(popup, position: sender.center).y
    popupy.constant = reposition(popup, position: sender.center).x

    }

    @IBAction func updateImage(sender: UIButton) {
        if id == 1 {
            id = 2
        }else {
            id = 1
        }

        self.number.image = UIImage(named: "\(id)")

    }


    func reposition (element: UIView, position: CGPoint)->CGPoint
    {
        var p = CGPoint()

        p.x = position.x - (element.frame.size.height / 2 )
        p.y = position.y - (element.frame.size.width / 2)

        return p
    }
}

【问题讨论】:

    标签: swift uiview autolayout


    【解决方案1】:

    由于您希望随着时间的推移使视图相对于不同视图居中,一种方法是根据需要添加和删除约束。

    以下代码创建NSLayoutConstraints 以使视图相对于另一个视图居中:

    class ViewController: UIViewController {
    
        @IBOutlet weak var boxView: UIView!
        var boxCenterX: NSLayoutConstraint?
        var boxCenterY: NSLayoutConstraint?
    
        func centerBoxOnView(v: UIView) {
            // Remove previous constraints on center, if any
            boxCenterX?.active = false
            boxCenterY?.active = false
    
            boxCenterX = NSLayoutConstraint(item: boxView, attribute: .CenterX,
                relatedBy: .Equal, toItem: v, attribute: .CenterX,
                multiplier: 1, constant: 0)
            boxCenterX?.active = true
    
            boxCenterY = NSLayoutConstraint(item: boxView, attribute: .CenterY,
                relatedBy: .Equal, toItem: v, attribute: .CenterY,
                multiplier: 1, constant: 0)
            boxCenterY?.active = true
    
            self.view.layoutIfNeeded()
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Start box at center of screen
            centerBoxOnView(self.view)
        }
    
        @IBAction func buttonPressed(button: UIButton) {
            centerBoxOnView(button)
        }
    }
    

    当您为boxView(您正在移动的视图)设置约束时,请确保您在情节提要中创建的centerX 和centerY 约束标记为占位符这样它们将在构建时被删除,并且不会干扰代码中创建的约束。


    如果您希望视图动画到位,请替换:

    self.view.layoutIfNeeded()
    

    与:

    UIView.animateWithDuration(1) {
        self.view.layoutIfNeeded()
    }
    

    【讨论】:

    • 效果很好...非常感谢。我试着通过这个例子来学习......自动布局的想法让我发疯:-)
    • 自动布局功能非常强大,值得了解,尤其是对于 Apple 不断推出的所有不同尺寸的设备。
    【解决方案2】:

    您应该为layoutconstraint 创建一个IBOutlet 而不是更改self.popup.center,并更改该约束的constant 以放置弹出窗口。

    您也可以尝试设置translatesAutoresizingMaskIntoConstraints = true 并使用.frame = 更改位置。这应该将框架更改转换为自动布局约束。这可能会产生问题,因为您已经激活了与新约束冲突的自动布局约束,因此我建议使用 IBOutlet 进行约束解决方案。

    【讨论】:

    • 感谢您的评论,我用我认为应该如何工作的方式更新了我的代码。但不知道我需要什么样的 NSLayoutConstraint
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多