bcylin/QuickTableViewController

[Help needed] Problems in changing underlying TableViewCell label

karstengresch opened this issue · 3 comments

Thanks for this wonderful project first - seems to make life much easier!

I'd like to color the labels of QuickTableViewController's rows, but can't get it to work.

Though I'm able applying a general style in AppDelegate with...

  let tableViewCellLabelAppearance = UILabel.appearance(whenContainedInInstancesOf: [UITableViewCell.self])
  tableViewCellLabelAppearance.textColor = Theme.textColor

...all other labels in all other TableViewCells get colored accordingly, except of those from QuickTableViewController.

My naive approach to get this working was...

  let optionRowLabelAppearance = UILabel.appearance(whenContainedInInstancesOf: [OptionRow.self])
  optionRowLabelAppearance.textColor = Theme.textColor

...but this was refused with the compiler error message:

Cannot convert value of type 'OptionRow<UITableViewCell'>.Type to expected element type 'UIAppearanceContainerType'

Wondering now what the preferred way is theming QuickTableViewController views?

Thanks and best wishes,

Karsten

Hi Karsten,

Thanks for the feedback. The label is contained in the associated UITableViewCell, instead of OptionRow itself. To fix the compiler error, it should be:

// When it's OptionRow<CustomOptionCell>
let optionRowLabelAppearance = UILabel.appearance(whenContainedInInstancesOf: [CustomOptionCell.self])
optionRowLabelAppearance.textColor = Theme.textColor

UIAppearance issue

I find that UILabel.appearance(whenContainedInInstancesOf: [UITableViewCell.self]) works alright when the cell is dequeued with an identifier set in the storyboard.

But somehow it doesn't work when the cell is either registered with a class:

tableView.register(UITableViewCell.self, forCellReuseIdentifier: "reuseIdentifier")

or initialized in code:

let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "reuseIdentifier")

Since QuickTableViewController initializes table view cells in code without using a storyboard, the labels in cells don't pick up the appearance settings. One way to work around this issue might be registering a nib object.

Workaround with a nib object

Add a CustomOptionCell.xib:

  1. drag in a Table View Cell object to replace the default view
  2. set its Style to Basic or Subtitle
  3. set the Custom Class to CustomOptionCell
  4. set the reuse identifier to CustomOptionCell, same as the type name

Register the nib to the table view with:

class CustomOptionCell: UITableViewCell {}
let typeName = "CustomOptionCell"
tableView.register(UINib(nibName: typeName, bundle: .main), forCellReuseIdentifier: typeName)

Instead of using the default OptionRow in the section, specify the associated cell type OptionRow<CustomOptionCell>.

Then the table view will dequeue the cell registered in the nib and the UIAppearance customization should work in those cells. Hope this helps.

Hi Ben,

thanks for your quick answer. So much appreciated!

Then the table view will dequeue the cell registered in the nib and the UIAppearance customization should work in those cells.
Hope this helps.
This indeed helped and I could successfully change the label color 👍

Unfortunately, the problem remains with SwitchCell and TapActionCell - got stuck creating a xib file directly using TapActionCell eg.

There should be an easier way to get the labels styled (maybe using

public init(style: UITableViewCellStyle, reuseIdentifier: String?)

? But I'm not really sure, how.

Any idea at your side?

Best wishes,

Karsten

Hi Karsten,

I tried it on the Example app.
https://github.com/bcylin/QuickTableViewController/compare/feature/ui-appearance

Although TapActionCell sets its text color during initialization, it seems no problem with the UIAppearance textColor on iOS 11.2 simulator.