Swift 4 - setNeedsDisplay和layoutIfNeeded不会在self.UIView上重绘UILabel

时间:2018-01-29 05:54:52

标签: swift uilabel redraw setneedsdisplay

基本上,我有一个自定义UILabel子类,它根据变量设置标签颜色。

class MyLabel: UILabel {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        textColor = GlobalVars.mainTextColor
    }
}

在我的视图控制器上,我有一个设置白色背景的按钮,并将文本颜色变量设置为黑色:

@IBAction func btnWhite(_ sender: UIButton) {
        GlobalVars.mainTextColor = UIColor.black
        GlobalVars.bgColor = UIColor.white
        self.view.backgroundColor = UIColor.white
        self.view.setNeedsDisplay()
        self.view.layoutIfNeeded()
        DispatchQueue.main.async { [weak self] in
            self?.view.setNeedsLayout()
            self?.view.layoutIfNeeded()
        }
    }

单击此项并更新变量后,我希望ViewController重绘标签,这将更新其文本颜色。如果我弹出VC并返回,这项工作正常,但我希望在单击按钮时更新显示。我在视图上有一堆标签,你的都被设置为myLabel类。我不想手动编写对屏幕上每个标签的更改,我只想重新绘制它。 UIView不是自定义类,只是View Controller附带的默认UIView。这应该在主线程上发生,但我尝试添加dispatch.main.async以防万一。我希望最终不需要两者。 Image of my view controller layout here

当我点击按钮时,背景变为白色,但标签文字颜色不会更新,我相信这是因为它没有重绘它们。有一个第二个按钮btnBlack,它可以切换到与亮/暗模式效果完全相反的按钮。

思想?

3 个答案:

答案 0 :(得分:0)

您必须在按钮Click方法

中更改TextColor
@IBAction func btnWhite(_ sender: UIButton) {
     myCustomLabel.textColor = UIColor.blue
} 

并且无需调用下面提到的方法

self.view.setNeedsDisplay()
self.view.layoutIfNeeded()

注意:没有其他方法可以更改UIlabel TextColor

答案 1 :(得分:0)

每当GlobalVars.mainTextColorGlobalVars.bgColor值发生变化时,您必须再次设置所有标签的颜色。

一种选择是使用通知。您可以在didSet全局变量上发布通知,并在MyLabel课程中捕获通知并更新颜色。

class GlobalVars {
    static let onChangeColorNotification = "onChangeColorNotification"
    static var mainTextColor:UIColor? {
        didSet {
            NotificationCenter.default.post(Notification.init(name: Notification.Name(rawValue: onChangeColorNotification)))
        }
    }
}

MyLabel班级

class MyLabel: UILabel {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        onChangeGlogabColor()
        NotificationCenter.default.addObserver(self, selector: #selector(onChangeGlogabColor), name: NSNotification.Name(rawValue: GlobalVars.onChangeColorNotification), object: nil)
    }
    @objc func onChangeGlogabColor() {
        textColor = GlobalVars.mainTextColor
    }
}

您可以对所有自定义类(如MyButtonMyView执行相同操作,捕获通知并更新颜色。

您不必致电setNeedsDisplay()layoutIfNeeded()

@IBAction func btnWhite(_ sender: UIButton) {
    GlobalVars.mainTextColor = UIColor.black
    GlobalVars.bgColor = UIColor.white
    self.view.backgroundColor = UIColor.white        
}

答案 2 :(得分:0)

Bilal的回答是正确的。有时需要采用完全不同的方法。感谢新鲜的眼睛,这是最后的代码。

添加以下代码并将所有标签设置为此“MyLabel”类。然后,只要更改GlobalVars.mainTextColor变量,标签就会更新其文本颜色。这可以适用于UIButton,或者当var变化时需要更新的任何属性。这会在任何加载的VC上更新此类的任何标签。这也解决了我的根VC标签也需要更新的问题,因为它们也已经用原始颜色绘制,非常光滑!

class MyLabel: UILabel {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        textColor = GlobalVars.mainTextColor
        NotificationCenter.default.addObserver(self, selector: #selector(onChangeGlobalColor), name: NSNotification.Name(rawValue: "onChangeColorNotification"), object: nil)
    }
    @objc func onChangeGlobalColor() {
        textColor = GlobalVars.mainTextColor
    }
}

struct GlobalVars {
    static var mainTextColor:UIColor = UIColor() {
        didSet {
            NotificationCenter.default.post(Notification.init(name: Notification.Name(rawValue: "onChangeColorNotification")))
        }
    }

@IBAction func btnWhite(_ sender: UIButton) {
        GlobalVars.mainTextColor = UIColor.black
        self.view.backgroundColor = UIColor.white
    }
@IBAction func btnBlack(_ sender: UIButton) {
        GlobalVars.mainTextColor = UIColor.white
        self.view.backgroundColor = UIColor.black
    }