如何根据设备主题更改collectionview单元格颜色(按照我的配色方案)
Posted
技术标签:
【中文标题】如何根据设备主题更改collectionview单元格颜色(按照我的配色方案)【英文标题】:How to change collectionview cells color based on device theme (following my color scheme) 【发布时间】:2020-10-28 15:27:08 【问题描述】:概述:
我正在使用集合视图构建键盘扩展。我希望单元格根据设备主题(亮/暗)更改颜色。目前,当我为我的 collectionview 单元格设置配色方案时,它们不起作用。我正在用“///”注释标记我的代码有问题的部分。
资源:
我找到了this RayWenderlich project,我喜欢他们处理颜色变化的方式,所以我复制了它。
我的代码:
我有 3 个课程:
-
键盘视图控制器
包含键盘按钮的自定义视图
自定义 collectionview 单元格
CollectionView 单元格
class KeyboardKeys: UICollectionViewCell
var defaultColor = UIColor.white
var highlighColor = UIColor.lightGray.withAlphaComponent(0.6)
let label: UILabel =
let iv = UILabel()
iv.translatesAutoresizingMaskIntoConstraints = false
iv.contentMode = .scaleAspectFit
iv.font = UIFont.systemFont(ofSize: 20)
iv.clipsToBounds = true
iv.numberOfLines = 1
iv.textAlignment = .center
return iv
()
override init(frame: CGRect)
super.init(frame: .zero)
commonInit()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
commonInit()
func commonInit()
contentView.addSubview(label)
label.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
label.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
label.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
override func layoutSubviews()
super.layoutSubviews()
backgroundColor = isHighlighted ? highlighColor : defaultColor
自定义视图
class lettersKeyboard: UIView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
var keyView: UICollectionView!
let letters = ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"]
override init(frame: CGRect)
super.init(frame: frame)
commonInit()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
commonInit()
private func commonInit()
//If you find some errors it's because this is way different in my code. This is just a regulare collection view anyway
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
keyView = UICollectionView(frame: CGRect(x: 0.0, y: 0.0 , width: frame.width, height: 280), collectionViewLayout: layout)
keyView.setCollectionViewLayout(layout, animated: true)
keyView.isScrollEnabled = false
keyView.register(KeyboardKeys.self, forCellWithReuseIdentifier: "collectionCellId")
keyView.delegate = self
keyView.dataSource = self
addSubview(keyView)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
10
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = keyView.dequeueReusableCell(withReuseIdentifier: "collectionCellId", for: indexPath) as! KeyboardKeys
cell.label.text = letters[indexPath.row]
return cell
///I guess something is wrong here
func setColorScheme(_ colorScheme: ColorScheme)
let colorScheme = CColors(colorScheme: colorScheme)
for view in subviews
if let cell = view as? KeyboardKeys
cell.tintColor = colorScheme.buttonTextColor
cell.defaultColor = colorScheme.keysDefaultColor
cell.highlighColor = colorScheme.keysHighlightColor
配色方案结构
enum ColorScheme
case dark
case light
struct CColors
let keysDefaultColor: UIColor
let keysHighlightColor: UIColor
let buttonTextColor: UIColor
init(colorScheme: ColorScheme)
switch colorScheme
case .light:
keysDefaultColor = .systemRed
//UIColor.white
keysHighlightColor = UIColor.lightGray.withAlphaComponent(0.6)
buttonTextColor = .black
case .dark:
keysDefaultColor = .systemBlue
// UIColor.gray.withAlphaComponent(0.5)
keysHighlightColor = UIColor.lightGray.withAlphaComponent(0.5)
buttonTextColor = .white
键盘视图控制器
class KeyboardViewController: UIInputViewController
var letters : lettersKeyboard =
let m = lettersKeyboard(frame: .zero)
m.translatesAutoresizingMaskIntoConstraints = false
m.backgroundColor = .clear
return m
()
override func viewDidLoad()
super.viewDidLoad()
view.addSubview(letters)
letters.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
letters.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
letters.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
letters.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
//The rest is the default inputvc stuff
///Or here
override func textDidChange(_ textInput: UITextInput?)
// The app has just changed the document's contents, the document context has been updated.
let colorScheme: ColorScheme
let proxy = self.textDocumentProxy
if proxy.keyboardAppearance == UIKeyboardAppearance.dark
colorScheme = .dark
else
colorScheme = .light
letters.setColorScheme(colorScheme)
问题:
我不知道我做错了什么,因为我的代码适用于除了 collectionview 单元格之外的所有内容。我想存在另一种做这些事情的方法。那么如何根据我的配色方案根据设备的主题更改我的 collectionView 单元格的颜色?
【问题讨论】:
【参考方案1】:您确实应该重新加载集合视图,而不是试图找到作为键的子视图并更新它们。
将 colorScheme 模型传递给每个单元格,并在重新加载时设置颜色。
【讨论】:
是的,我认为@Jay 是对的。您需要重新加载集合视图(您的自定义键盘),并为简单起见将颜色作为计算属性,通过检查主题来给出结果。【参考方案2】:一个非常善良的人帮助我找到了这个解决方案。这里的问题是我忘记了视图的层次结构。
CollectionView 单元格
override func layoutSubviews()
super.layoutSubviews()
setupBackGround()
func setupBackGround()
backgroundColor = isHighlighted ? highlighColor : defaultColor
键盘视图控制器
func setColorScheme(_ colorScheme: ColorScheme)
let colorScheme = CColors(colorScheme: colorScheme)
for view in subviews
func setToRootView(view: UIView)
if let cell = view as? KeyboardKeys
cell.tintColor = colorScheme.buttonTextColor
cell.defaultColor = colorScheme.keysDefaultColor
cell.highlighColor = colorScheme.keysHighlightColor
cell.setBackground()
return
guard view.subviews.count > 0 else
return
view.subviews.forEach(setToRootView(view:))
setToRootView(view: self)
【讨论】:
以上是关于如何根据设备主题更改collectionview单元格颜色(按照我的配色方案)的主要内容,如果未能解决你的问题,请参考以下文章
当设备旋转而不将设备锁定为纵向模式时,如何将 collectionView 的所有项目保持在适当的位置?
根据 CollectionView 中的选择更改 ImageView