从 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()
我想做的是从 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()