从 class 外部调用标签位置和大小(Swift 4)

call label postion and size from outside of class (Swift4)

我想做的是从 class 外部分配标签的位置和大小。然后在 2 个单独的 classes 内调用标签以向其添加文本。如果可行的话,这将节省很多时间。

let backbutton = UILabel!
backbutton.translatesAutoresizingMaskIntoConstraints = false
backbutton.leftAnchor.constraint(equalTo: _, constant: 20).isActive = true
backbutton.topAnchor.constraint(equalTo: _, constant: 125).isActive = true
backbutton.widthAnchor.constraint(equalToConstant: 50).isActive = true
backbutton.heightAnchor.constraint(equalToConstant: 50).isActive = true

class nineViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        backbutton.text = String("red")

    }
}

class two: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        backbutton.text = String("two")
    }
}

您可以为 buttonText 设置不同的变量,并在他的 setter 中设置他的位置和大小,例如

var buttonText:String {
   didSet{
     backButton.text = buttonText
     setFontAndPosition()
   }
}

并在 viewController 中设置值

 override func viewDidLoad() {
        super.viewDidLoad()
        buttonText = "red"
    }

单独创建一个 Utilities class 以全局使用其中的函数。

实用工具:

class Utilities: NSObject
{
    class func createLabel(on view: UIView, horizontalAnchors hAnchors: (leading: CGFloat, leadingView: UIView, trailing: CGFloat, trailingView: UIView), verticalAnchors vAnchors: (top: CGFloat, topView: UIView, bottom: CGFloat, bottomView: UIView)) -> UILabel {

        let label = UILabel()
        view.addSubview(label)
        label.backgroundColor = UIColor.red

        label.translatesAutoresizingMaskIntoConstraints = false
        label.leadingAnchor.constraint(equalTo: hAnchors.leadingView.leadingAnchor, constant: hAnchors.leading).isActive = true
        label.trailingAnchor.constraint(equalTo: hAnchors.trailingView.trailingAnchor, constant: -hAnchors.trailing).isActive = true
        label.topAnchor.constraint(equalTo: vAnchors.topView.topAnchor, constant: vAnchors.top).isActive = true
        label.bottomAnchor.constraint(equalTo: vAnchors.bottomView.topAnchor, constant: -vAnchors.bottom).isActive = true

        return label
    }

    class func createLabel(on view: UIView, positionAnchors pAnchors: (leading: CGFloat, leadingView: UIView, top: CGFloat, topView: UIView), size: (width: CGFloat, height: CGFloat)) -> UILabel {

        let label = UILabel()
        view.addSubview(label)
        label.backgroundColor = UIColor.red

        label.translatesAutoresizingMaskIntoConstraints = false
        label.leadingAnchor.constraint(equalTo: pAnchors.leadingView.leadingAnchor, constant: pAnchors.leading).isActive = true
        label.topAnchor.constraint(equalTo: pAnchors.topView.topAnchor, constant: pAnchors.top).isActive = true
        label.widthAnchor.constraint(equalToConstant: size.width).isActive = true
        label.heightAnchor.constraint(equalToConstant: size.height).isActive = true

        return label
    }
}

在ViewController中:

@IBOutlet weak var autoLayedoutLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    let originY: CGFloat = 50
    let spacing: CGFloat = 16
    let width: CGFloat = 300
    let height: CGFloat = 50

    let label = Utilities.createLabel(on: view, positionAnchors: (spacing, view, originY, view), size: (width, height))
    label.text = "Label with Position Anchors & Size"
    label.backgroundColor = UIColor.red

    let label2 = Utilities.createLabel(on: view, horizontalAnchors: (spacing, view, spacing, view), verticalAnchors: (spacing + height, label, spacing, autoLayedoutLabel))
    label2.text = "Label with Horizontal & Vertical Anchors"
    label2.backgroundColor = UIColor.green
}

我发现直接使用global UILable是可行的。如果不需要管理太多标签,这是最简单的方法。

这里使用TabBarcontroller进行测试。

        let backbutton = UILabel()

        class MyTabBarController : UITabBarController {
            override func viewDidLoad() {
                  super.viewDidLoad()
               setViewControllers([SettingViewController(), NineViewController(), TwoViewController()], animated: false)
            }
        }


        class SettingViewController: UIViewController {

            override var tabBarItem: UITabBarItem!{
                get {
                    return UITabBarItem.init(title: "setting", image: nil, tag: 0)
                }
                set{
                    super.tabBarItem = newValue
                }

            }

            override func viewDidLoad() {
                  super.viewDidLoad()
                self.view.backgroundColor = UIColor.white
                self.view.addSubview(backbutton)
                backbutton.text = "cool"
                backbutton.translatesAutoresizingMaskIntoConstraints = false
                backbutton.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 20).isActive = true
                backbutton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 125).isActive = true
                backbutton.widthAnchor.constraint(equalToConstant: 50).isActive = true
                backbutton.heightAnchor.constraint(equalToConstant: 50).isActive = true
            }
        }

        class NineViewController: UIViewController {

            override var tabBarItem: UITabBarItem!{
                get {
                    return UITabBarItem.init(title: "nine", image: nil, tag: 0)
                }
                set{
                    super.tabBarItem = newValue
                }

            }
            override func viewDidLoad() {
                super.viewDidLoad()
                   self.view.backgroundColor = UIColor.white
                backbutton.text = String("red")
            }
            override func viewWillAppear(_ animated: Bool) {
                super.viewWillAppear(animated)
                backbutton.text = String("red-Appear")
            }

        }

        class TwoViewController: UIViewController {
            override var tabBarItem: UITabBarItem!{
                get {
                    return UITabBarItem.init(title: "two", image: nil, tag: 0)
                }
                set{
                    super.tabBarItem = newValue
                }

            }
            override func viewDidLoad() {
                super.viewDidLoad()
                   self.view.backgroundColor = UIColor.white
                backbutton.text = String("two")
            }

            override func viewWillAppear(_ animated: Bool) {
                super.viewWillAppear(animated)
                backbutton.text = String("two-Appear")
            }
        }

如果您更喜欢在其中定义标签 class。您可以这样定义全局 UILabel:

weak var backbutton: UILabel!

    class SettingViewController: UIViewController {
                let mybutton = UILabel()
                backbutton = mybutton
               // continue
     }

您不需要更改任何其他代码。

现在是故事的第二部分。如果你想在任何视图之外设置一个全局 UILabel,那是可能的。没有约束就很简单了:

let backbutton: UILabel! = {
let button = UILabel()
button.text = "test"
button.frame = CGRect.init(x: 200, y: 200, width: 50, height: 50)
return button
}()

设置视图更改如下:

        class SettingViewController: UIViewController {

            override var tabBarItem: UITabBarItem!{
                get {
                    return UITabBarItem.init(title: "setting", image: nil, tag: 0)
                }
                set{
                    super.tabBarItem = newValue
                }

            }


            override func viewDidLoad() {
                super.viewDidLoad()
                self.view.backgroundColor = UIColor.white
                self.view.addSubview(backbutton)
            }
        }

很明显SettingVC里面只有一行。但是如果需要使用约束,我们应该怎么办呢?其他都没问题,就是UILabel约束的位置要看UILabel的superView。所以这里可以使用扩展来简化事情。

    let specialLabelTag =  1001
    let backbutton: UILabel! = {
        let button = UILabel()
        button.tag = specialLabelTag
        button.text = "test" // for test purpose
        button.translatesAutoresizingMaskIntoConstraints = false
        button.widthAnchor.constraint(equalToConstant: 50).isActive = true
        button.heightAnchor.constraint(equalToConstant: 50).isActive = true
        return button
    }()
    extension UILabel{
         override open func didMoveToSuperview() {
            superview?.didMoveToSuperview()
            if(tag == specialLabelTag){
                leftAnchor.constraint(equalTo: superview!.leftAnchor, constant: 20).isActive = true
                topAnchor.constraint(equalTo: superview!.topAnchor, constant: 125).isActive = true
              }
        }

扩展中使用的标签是为了标识全局UILabel,以免影响其他UILabel。扩展中只需要位置约束。 SettingUP vc 和之前一样。

现在您可以在没有任何视图的情况下构建标签 class。但是您必须将它们添加到某处并根据需要修改文本。希望这是问题的答案。

顺便说一句,您可以使用上面的代码将 UILabel 子class 到 MyUILabel,然后将其设为全局(只需放在任何 class 之外)。这会容易得多,因为您不需要使用 specialLabelTag。

 let backbutton = MyUILabel()