首页 文章

有可能在一个地方更改iOS移动应用程序的所有UILabel颜色吗?

提问于
浏览
1

每当应用程序加载时,我必须在一个地方更改所有UILabel颜色 . 我知道有一种方法可以通过设置textColor来单独更改UILabel的颜色 . 因为这是花时间以编程方式或使用StoryBoard更改所有UILabel个体的过程 .

我需要通过在一个地方添加textColor来改变标签颜色来了解简化方法 . 即使是改变控制器标签颜色也很好 . 例如 . 通过UILabel类别的方式 .

任何片段都有助于我实现这一目标 . 单个Controller的UIlabel颜色的代码很好 .

1 回答

  • 1

    有各种方法来处理这个问题 . 您可能不应该使用tintColor属性,因为Apple打算将其作为可点击项目的视觉提示 .

    我建议创建 UILabel 的自定义子类 . 我们称之为 ColorChangingLabel . 定义 NotificationCenter 通知名称 labelColorChanged ,并在广播该通知时,将键/值对 textColor 添加到包含新文本颜色的通知的userInfo中 . 如果您希望能够更改它,还可以添加可选的背景颜色键/值对 . (实际上,您可以添加一整套不同的键/值对,以便更改自定义标签的不同属性 . )

    在您的自定义UILabel子类中:

    • 定义函数 addLabelColorChangedObserver() . 让该函数调用 NotificationCenter 为您的 labelColorChanged 通知添加一个观察者,该通知在通知的 userInfo 中查找 textColor 并使用该颜色更改标签的文本颜色 .

    • 覆盖 init(frame:)init(coder:) 并让这些方法调用 addLabelColorChangedObserver() 函数 .

    • 为您的UILabel子类实现deinit方法,删除其观察者 .

    在您的应用中,当您希望标签更改其颜色时,请使用包含新文本颜色的 userInfo 字典发布通知 .

    一旦你've done all that, go through all of your app'的故事板选择每个标签,并使用"identity inspector"将对象的类更改为自定义 ColorChangingLabel 类 . 应该这样做 .

    编辑:

    如果您希望能够基于视图控制器在视图控制器上定位颜色更改,则可以将标签设置为具有 owningViewController 属性,并且在设置它们时,如果将 owningViewController 添加为 object 参数,则将它们添加为 labelColorChanged 通知的观察员 . 然后,告诉单个视图控制器's labels to change their color, you' d发送一个目标视图控制器的通知作为 object 参数 .

    这里棘手的一点是在标签上设置 owningViewController 属性 . 您加载了'd want a method to be able to set that up automatically when your view controller'个视图 . 也许在您的视图中,控制器's viewDidLoad method you' d调用一个递归遍历视图控制器层次结构的方法,将自身设置为 owningViewController ,用于所有 ColorChangingLabel .

    编辑2:

    我实现了如上所述的CustomLabel类 . 这是代码:

    //
    //  CustomLabel.swift
    //  CustomLabel
    //
    //  Created by Duncan Champney on 4/20/17.
    //  Copyright © 2017 Duncan Champney. All rights reserved.
    //
    
    import UIKit
    
    let labelColorChangedNotice: NSNotification.Name  = NSNotification.Name("labelColorChangedNotice")
    let textColorKey = "textColor"
    let backgroundColorKey = "backgroundColor"
    
    class CustomLabel: UILabel {
      static var classLabelColorChangeObserver: Any!
    
      static var startingTextColor: UIColor?
      static var startingTextBGColor: UIColor?
    
      override class func initialize() {
    
        //Have the CustomLabel class add an observer to record changes to the text color and/or background color even if there are no CustomLabel instances on-screen.
        classLabelColorChangeObserver = NotificationCenter.default.addObserver(forName: labelColorChangedNotice,
           object: nil,
           queue: nil ) {
            notification in
            if let textColor = notification.userInfo?[textColorKey] as? UIColor {
              CustomLabel.startingTextColor = textColor
            }
            if let backgroundColor = notification.userInfo?[backgroundColorKey] as? UIColor {
              CustomLabel.startingTextBGColor = backgroundColor
            }
        }
      }
    
      var labelColorChangeObserver: Any?
    
      override init(frame: CGRect) {
        super.init(frame: frame)
        labelColorChangeObserver = addLabelColorChangedObserver()
      }
    
      required init?(coder: NSCoder) {
        super.init(coder: coder)
        labelColorChangeObserver = addLabelColorChangedObserver()
      }
    
      deinit {
        if let labelColorChangeObserver = labelColorChangeObserver {
          NotificationCenter.default.removeObserver(observer: labelColorChangeObserver)
        }
      }
    
      func addLabelColorChangedObserver() {
        if let startingTextColor = CustomLabel.startingTextColor {
          self.textColor = startingTextColor
        }
        if let startingTextBGColor = CustomLabel.startingTextBGColor {
          self.backgroundColor = startingTextBGColor
        }
        labelColorChangeObserver =  NotificationCenter.default.addObserver(forName: labelColorChangedNotice,
          object: nil,
          queue: nil ) {
            [weak self] //Use a capture list to avoid a retain cycle
            notification in
    
            //Once we're in the notification's closure, capture self strongly, or bail if it's nil.
            guard let strongSelf = self else {
              return
            }
    
            //If we've been given a textColor, install it in the label.
            if let textColor = notification.userInfo?[textColorKey] as? UIColor {
              strongSelf.textColor = textColor
            }
            //If we've been given a backgroundColor, install it in the label.
            if let backgroundColor = notification.userInfo?[backgroundColorKey] as? UIColor {
              strongSelf.backgroundColor = backgroundColor
            }
        }
      }
    }
    

相关问题