Центрирующая кнопка с фиксированной шириной разрывов NSLayoutConstraint - PullRequest
0 голосов
/ 06 февраля 2019

У меня интересная проблема.Мое приложение полностью управляется с помощью кода вместо раскадровок.У меня есть UIViewController, который представлен программно.Это создает кнопку и ограничения для нее.

Вот так выглядит код контроллера.

import Foundation
import UIKit

class CreateViewController: UIViewController {

    lazy var button: UIButton = {
        let button =  UIButton()
        button.layer.bounds = CGRect(x: 0, y: 0, width: 50, height: 50)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = .green
        return button
    }()

    func setupViews() {
        self.view.addSubview(button)
    }

    func setupConstraints() {
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[button]-100-|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: ["button": button]))
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[button(50)]-|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: ["button": button]))
    }

    override func viewDidLoad() {
        setupViews()
        setupConstraints()
    }
}

Выдает эту ошибку.

(
    "<NSLayoutConstraint:0x60000288bb60 UIButton:0x7fa1ab422680.leading == UILayoutGuide:0x6000032da760'UIViewLayoutMarginsGuide'.leading NSSpace(0)   (active)>",
    "<NSLayoutConstraint:0x60000288bb10 UIButton:0x7fa1ab422680.width == 50   (active)>",
    "<NSLayoutConstraint:0x60000288d7c0 UILayoutGuide:0x6000032da760'UIViewLayoutMarginsGuide'.trailing == UIButton:0x7fa1ab422680.trailing NSSpace(0)   (active)>",
    "<NSLayoutConstraint:0x6000028fe990 'UIView-Encapsulated-Layout-Width' UIView:0x7fa1ab4224a0.width == 375   (active)>",
    "<NSLayoutConstraint:0x60000288fe30 'UIView-leftMargin-guide-constraint' H:|-(16)-[UILayoutGuide:0x6000032da760'UIViewLayoutMarginsGuide'](LTR)   (active, names: '|':UIView:0x7fa1ab4224a0 )>",
    "<NSLayoutConstraint:0x60000288d180 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6000032da760'UIViewLayoutMarginsGuide']-(16)-|(LTR)   (active, names: '|':UIView:0x7fa1ab4224a0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x60000288d7c0 UILayoutGuide:0x6000032da760'UIViewLayoutMarginsGuide'.trailing == UIButton:0x7fa1ab422680.trailing NSSpace(0)   (active)>

Моя цель здесь довольно проста.Я хочу, чтобы кнопка была на 100 пикселей выше дна, имела горизонтальное центрирование и фиксированную ширину и высоту.

Вот как создается экземпляр контроллера.Он существует внутри

        let nav2 = UINavigationController()
        let create = CreateViewController()
        nav2.viewControllers = [create]
        nav2.navigationBar.isTranslucent = false
        ...
        let tabs = UITabBarController()
        tabs.viewControllers = [..., nav2, ...]

        tabs.delegate = self

. Любая помощь в понимании того, почему эти ограничения нарушаются, будет принята с благодарностью!Если какая-то часть вопроса неясна, просто дайте мне знать.

К вашему сведению, результирующее представление выглядит так:

the button is not centered here

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Центрирование элемента с помощью языка визуальных форматов затруднено.

Вы можете легко сделать это, используя .centerXAnchor:

class CreateViewController: UIViewController {

    lazy var button: UIButton = {
        let button =  UIButton()
        // next line is not needed
//      button.layer.bounds = CGRect(x: 0, y: 0, width: 50, height: 50)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = .green
        return button
    }()

    func setupViews() {
        self.view.addSubview(button)
    }

    func setupConstraints() {

        NSLayoutConstraint.activate([

            // button width of 50
            button.widthAnchor.constraint(equalToConstant: 50.0),

            // button height of 50
            button.heightAnchor.constraint(equalToConstant: 50.0),

            // bottom of button 100-pts from bottom of view
            // note: contant is negative!
            button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -100),

            // center the button horizontally
            button.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            ])

    }

    override func viewDidLoad() {
        setupViews()
        setupConstraints()
    }
}
0 голосов
/ 06 февраля 2019

вы можете попробовать следующий способ добавить ограничения, которые являются более быстрыми и чистыми

func setupConstraints() {
    let topConstraint = NSLayoutConstraint(item: button,
                                           attribute: .top,
                                           relatedBy: .equal,
                                           toItem: self.view,
                                           attribute: .top,
                                           multiplier: 1,
                                           constant: 100)

    let bottomConstraint = NSLayoutConstraint(item: button,
                                              attribute: .left,
                                              relatedBy: .equal,
                                              toItem: self.view,
                                              attribute: .left,
                                              multiplier: 1,
                                              constant: 100)
    self.view.addConstraints([topConstraint,bottomConstraint])

}

, хотя я хотел знать, почему вы добавляете ограничения к кнопке, когда вы можете объявить x и y во времяинициализация.если вам нужна помощь, я добавил код для нее, где кнопка находится в центре, надеюсь, это поможет.

 lazy var button: UIButton = {
    let button =  UIButton()
    button.frame = CGRect(x: UIScreen.main.bounds.width/2-25, y: UIScreen.main.bounds.height/2-25, width: 50, height: 50)
    button.backgroundColor = .green
    return button
     }()  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...