Update on Dec 2015:
Apple now discourages overriding -traitCollection
. Please consider using other workarounds. From the doc:
IMPORTANT
Use the
traitCollection
property directly. Do not override it. Do not provide a custom implementation.
Original Answer:
The existing answer is great. It explained that the problem is that:
-dequeueReusableCellWithIdentifier:
returns a cell without a validcell.traitCollection
, andcell.traitCollection
isreadonly
.
The proposed workaround is to temporarily add the cell to the table view. However, this does NOT work if we are in, say, -viewDidLoad
, in which the traitCollection
of the table view, or the view of the view controller, or even the view controller itself, is not valid yet.
Here, I propose another workaround, which is to override traitCollection
of the cell. To do so:
-
Create a custom subclass of
UITableViewCell
for the cell (which you probably did already). -
In the custom subclass, add a
- (UITraitCollection *)traitCollection
method, which overrides the getter of thetraitCollection
property. Now, you can return any validUITraitCollection
you like. Here’s a sample implementation:// Override getter of traitCollection property // https://stackoverflow.com/a/28514006/1402846 - (UITraitCollection *)traitCollection { // Return original value if valid. UITraitCollection* originalTraitCollection = [super traitCollection]; if(originalTraitCollection && originalTraitCollection.userInterfaceIdiom != UIUserInterfaceIdiomUnspecified) { return originalTraitCollection; } // Return trait collection from UIScreen. return [UIScreen mainScreen].traitCollection; }
Alternatively, you can return a suitable
UITraitCollection
created using any one of its create methods, e.g.:+ (UITraitCollection *)traitCollectionWithDisplayScale:(CGFloat)scale + (UITraitCollection *)traitCollectionWithTraitsFromCollections:(NSArray *)traitCollections + (UITraitCollection *)traitCollectionWithUserInterfaceIdiom:(UIUserInterfaceIdiom)idiom + (UITraitCollection *)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass + (UITraitCollection *)traitCollectionWithVerticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
Or, you can even make it more flexible by doing this:
// Override getter of traitCollection property // https://stackoverflow.com/a/28514006/1402846 - (UITraitCollection *)traitCollection { // Return overridingTraitCollection if not nil, // or [super traitCollection] otherwise. // overridingTraitCollection is a writable property return self.overridingTraitCollection ?: [super traitCollection]; }
This workaround is compatible with iOS 7 because the traitCollection
property is defined in iOS 8+, and so, in iOS 7, no one will call its getter, and thus our overriding method.