Files
André Pacheco Neves 739a4f5d78 Fix skeletons interfering with attributed strings in text-based views (#520)
When enabling skeleton mode in a text-based view (`UILabel`,
`UITextView`, `UITextField`), it sets the `textColor` to `.clear`,
which is fine when `text` is used, but causes problems when
`attributedText` is used, as it effectively "resets" the string to have
a single color.

Additionally, when a `UILabel` is nested inside a `UIStackView` a
dummy string `" "` was set on the label's `text` so that it didn't have
a 0 height content size. However, this workaround didn't consider the
case where the label already had a non-empty text, meaning that this
(intrusive) `text = " "` broke existing code by clearing the label's
contents.

By improving the corresponding `RecoverableXState` structs, we are able
to preserve each element's contents and state as skeleton is disabled.

Fixes #518.

## Changes

- Create new `RecoverableLabelState` containing a `attributedText` and
`text`, and use it on `UILabel`.

- Update `RecoverableTextViewState` and `RecoverableTextFieldState` to
have a `attributedText`.

- Check if `UILabel`'s `text` is empty before setting dummy value when
enabling skeleton mode in a label nested inside a `UIStackView`.
2022-10-20 12:59:00 +02:00

87 lines
2.2 KiB
Swift

//
// RecoverableViewState.swift
// SkeletonView
//
// Created by Juanpe Catalán on 13/05/2018.
// Copyright © 2018 SkeletonView. All rights reserved.
//
import UIKit
struct RecoverableViewState {
var backgroundColor: UIColor?
var cornerRadius: CGFloat
var clipToBounds: Bool
var isUserInteractionsEnabled: Bool
init(view: UIView) {
self.backgroundColor = view.backgroundColor
self.clipToBounds = view.layer.masksToBounds
self.cornerRadius = view.layer.cornerRadius
self.isUserInteractionsEnabled = view.isUserInteractionEnabled
}
}
struct RecoverableLabelState {
var attributedText: NSAttributedString? // we mess with `textColor`, which impacts attributed string if defined
var text: String? // we mess with `text` if the label is within a `UIStackView`
var textColor: UIColor?
init(view: UILabel) {
if let attributedText = view.attributedText {
self.attributedText = attributedText
} else {
self.text = view.text
}
self.textColor = view.textColor
}
}
struct RecoverableTextViewState {
var attributedText: NSAttributedString? // we mess with `textColor`, which impacts attributed string if defined
var textColor: UIColor?
init(view: UITextView) {
self.attributedText = view.attributedText
self.textColor = view.textColor
}
}
struct RecoverableTextFieldState {
var attributedText: NSAttributedString? // we mess with `textColor`, which impacts attributed string if defined
var textColor: UIColor?
var placeholder: String?
init(view: UITextField) {
self.attributedText = view.attributedText
self.textColor = view.textColor
self.placeholder = view.placeholder
}
}
struct RecoverableImageViewState {
var image: UIImage?
init(view: UIImageView) {
self.image = view.image
}
}
struct RecoverableButtonViewState {
var title: String?
init(view: UIButton) {
self.title = view.titleLabel?.text
}
}
struct RecoverableTableViewHeaderFooterViewState {
var backgroundViewColor: UIColor?
init(view: UITableViewHeaderFooterView) {
self.backgroundViewColor = view.backgroundView?.backgroundColor
}
}