はじめに
xibで View
などの色にColor Assetの色を指定している場合、コードで色を変更すると想定外の挙動をすることがあります。
環境
- Xcode 10.3
- swift 5.0
準備
- Assets.xcassetsにColor Assetを作成する
適当に下記のように色を作成。
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
label.textColor = .blue
colorView.backgroundColor = .blue
label.backgroundColor = .green
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ColorTableViewCell", for: indexPath) as! ColorTableViewCell
cell.label.text = "Test \(indexPath.row)"
cell.label.textColor = .blue
cell.label.backgroundColor = .green
return cell
}
問題点
上記の準備をしたものを実行する。
期待値
結果
しかし、結果は下記のような表示。
Color Assetの色を指定していないLabelの背景色は変更されていますが、Color Assetの色を指定した部分は色が変わっていない!!
解決策
無難な解決策としてはxibの色指定をColor Assetをやめて Custom
を設定すること!!
Color Assetの色を指定しているとxibが読み込まれた後に再度色が設定されるらしい...
とりあえず viewDidload
viewWillAppear
はダメで viewDidAppear
で設定すると期待通り設定できました。
セルの場合 awakeFromNib
で設定してもダメでした。
2019/12/15追記
この記事に DispatchQueue.main.async
を使うと viewDidload
でも色変更ができるというのをみつけました。試してみたところ色がちゃんと変更されました。が、ただ DispatchQueue.main.async
を使うとなんでここで使ってるんだ?とあとで見た人が思うので下記のようにコメントをつけた方がいいでしょう
override func viewDidLoad() {
super.viewDidLoad()
// よくわからんけど動いた
DispatchQueue.main.async {
self.label.textColor = .blue
self.colorView.backgroundColor = .blue
self.label.backgroundColor = .green
}
}
さいごに
セルのラベルの色を条件によって変えようと思ったら初期表示のときに色が変わらない!!というのに直面し色々調べた結果、Color Assetが原因なのに気づきました。
Color Assetは便利だけど思わぬ挙動があるので気をつけましょう