Layout improvements
This commit is contained in:
parent
459564ae6b
commit
61a07e9a5b
|
@ -23,22 +23,8 @@ public final class StatusCardControl: UIControl {
|
||||||
private let titleLabel = UILabel()
|
private let titleLabel = UILabel()
|
||||||
private let linkLabel = UILabel()
|
private let linkLabel = UILabel()
|
||||||
|
|
||||||
private lazy var compactImageConstraints = [
|
private var layout: Layout?
|
||||||
imageView.heightAnchor.constraint(equalTo: heightAnchor),
|
private var layoutConstraints: [NSLayoutConstraint] = []
|
||||||
imageView.widthAnchor.constraint(equalToConstant: 85),
|
|
||||||
heightAnchor.constraint(equalToConstant: 85).priority(.defaultLow - 1),
|
|
||||||
heightAnchor.constraint(greaterThanOrEqualToConstant: 85)
|
|
||||||
]
|
|
||||||
|
|
||||||
private lazy var largeImageConstraints = [
|
|
||||||
imageView.heightAnchor.constraint(
|
|
||||||
equalTo: imageView.widthAnchor,
|
|
||||||
multiplier: 21 / 40
|
|
||||||
)
|
|
||||||
// This priority is important or constraints break;
|
|
||||||
// it still renders the card correctly.
|
|
||||||
.priority(.defaultLow - 1),
|
|
||||||
]
|
|
||||||
|
|
||||||
public override var isHighlighted: Bool {
|
public override var isHighlighted: Bool {
|
||||||
didSet { highlightView.isHidden = !isHighlighted }
|
didSet { highlightView.isHidden = !isHighlighted }
|
||||||
|
@ -85,6 +71,7 @@ public final class StatusCardControl: UIControl {
|
||||||
labelStackView.layoutMargins = .init(top: 10, left: 10, bottom: 10, right: 10)
|
labelStackView.layoutMargins = .init(top: 10, left: 10, bottom: 10, right: 10)
|
||||||
labelStackView.isLayoutMarginsRelativeArrangement = true
|
labelStackView.isLayoutMarginsRelativeArrangement = true
|
||||||
labelStackView.axis = .vertical
|
labelStackView.axis = .vertical
|
||||||
|
labelStackView.spacing = 2
|
||||||
|
|
||||||
containerStackView.addArrangedSubview(imageView)
|
containerStackView.addArrangedSubview(imageView)
|
||||||
containerStackView.addArrangedSubview(labelStackView)
|
containerStackView.addArrangedSubview(labelStackView)
|
||||||
|
@ -106,8 +93,6 @@ public final class StatusCardControl: UIControl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func configure(card: Card) {
|
public func configure(card: Card) {
|
||||||
let isCompact = card.width == card.height
|
|
||||||
|
|
||||||
if let host = card.url?.host {
|
if let host = card.url?.host {
|
||||||
accessibilityLabel = "\(card.title) \(host)"
|
accessibilityLabel = "\(card.title) \(host)"
|
||||||
} else {
|
} else {
|
||||||
|
@ -120,26 +105,17 @@ public final class StatusCardControl: UIControl {
|
||||||
|
|
||||||
imageView.sd_setImage(
|
imageView.sd_setImage(
|
||||||
with: card.imageURL,
|
with: card.imageURL,
|
||||||
placeholderImage: isCompact ? newsIcon : photoIcon
|
placeholderImage: icon(for: card.layout)
|
||||||
) { [weak imageView] image, _, _, _ in
|
) { [weak self] image, _, _, _ in
|
||||||
if image != nil {
|
if image != nil {
|
||||||
imageView?.contentMode = .scaleAspectFill
|
self?.imageView.contentMode = .scaleAspectFill
|
||||||
self.containerStackView.setNeedsLayout()
|
|
||||||
self.containerStackView.layoutIfNeeded()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLayoutConstraint.deactivate(compactImageConstraints + largeImageConstraints)
|
self?.containerStackView.setNeedsLayout()
|
||||||
|
self?.containerStackView.layoutIfNeeded()
|
||||||
if isCompact {
|
|
||||||
containerStackView.alignment = .center
|
|
||||||
containerStackView.axis = .horizontal
|
|
||||||
NSLayoutConstraint.activate(compactImageConstraints)
|
|
||||||
} else {
|
|
||||||
containerStackView.alignment = .fill
|
|
||||||
containerStackView.axis = .vertical
|
|
||||||
NSLayoutConstraint.activate(largeImageConstraints)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateConstraints(for: card.layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func didMoveToWindow() {
|
public override func didMoveToWindow() {
|
||||||
|
@ -150,14 +126,48 @@ public final class StatusCardControl: UIControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var newsIcon: UIImage? {
|
private func updateConstraints(for layout: Layout) {
|
||||||
UIImage(systemName: "newspaper.fill")
|
guard layout != self.layout else { return }
|
||||||
|
self.layout = layout
|
||||||
|
|
||||||
|
NSLayoutConstraint.deactivate(layoutConstraints)
|
||||||
|
|
||||||
|
switch layout {
|
||||||
|
case .large(let aspectRatio):
|
||||||
|
containerStackView.alignment = .fill
|
||||||
|
containerStackView.axis = .vertical
|
||||||
|
layoutConstraints = [
|
||||||
|
imageView.widthAnchor.constraint(
|
||||||
|
equalTo: imageView.heightAnchor,
|
||||||
|
multiplier: aspectRatio
|
||||||
|
)
|
||||||
|
// This priority is important or constraints break;
|
||||||
|
// it still renders the card correctly.
|
||||||
|
.priority(.defaultLow - 1),
|
||||||
|
]
|
||||||
|
case .compact:
|
||||||
|
containerStackView.alignment = .center
|
||||||
|
containerStackView.axis = .horizontal
|
||||||
|
layoutConstraints = [
|
||||||
|
imageView.heightAnchor.constraint(equalTo: heightAnchor),
|
||||||
|
imageView.widthAnchor.constraint(equalToConstant: 85),
|
||||||
|
heightAnchor.constraint(equalToConstant: 85).priority(.defaultLow - 1),
|
||||||
|
heightAnchor.constraint(greaterThanOrEqualToConstant: 85)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
private var photoIcon: UIImage? {
|
NSLayoutConstraint.activate(layoutConstraints)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func icon(for layout: Layout) -> UIImage? {
|
||||||
|
switch layout {
|
||||||
|
case .compact:
|
||||||
|
return UIImage(systemName: "newspaper.fill")
|
||||||
|
case .large:
|
||||||
let configuration = UIImage.SymbolConfiguration(pointSize: 32)
|
let configuration = UIImage.SymbolConfiguration(pointSize: 32)
|
||||||
return UIImage(systemName: "photo", withConfiguration: configuration)
|
return UIImage(systemName: "photo", withConfiguration: configuration)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func apply(theme: Theme) {
|
private func apply(theme: Theme) {
|
||||||
layer.borderColor = theme.separator.cgColor
|
layer.borderColor = theme.separator.cgColor
|
||||||
|
@ -165,6 +175,21 @@ public final class StatusCardControl: UIControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extension StatusCardControl {
|
||||||
|
enum Layout: Equatable {
|
||||||
|
case compact
|
||||||
|
case large(aspectRatio: CGFloat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Card {
|
||||||
|
var layout: StatusCardControl.Layout {
|
||||||
|
return width == height || image == nil
|
||||||
|
? .compact
|
||||||
|
: .large(aspectRatio: CGFloat(width) / CGFloat(height))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private extension UILayoutPriority {
|
private extension UILayoutPriority {
|
||||||
static let zero = UILayoutPriority(rawValue: 0)
|
static let zero = UILayoutPriority(rawValue: 0)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue