Skip to content

Commit

Permalink
Migrate ItemTableViewCell to programmatic layout
Browse files Browse the repository at this point in the history
  • Loading branch information
hartlco committed Dec 11, 2021
1 parent d6a7a0e commit bcbc461
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 180 deletions.
6 changes: 0 additions & 6 deletions Icro.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
C5046525274F77C60004B812 /* Font+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = C550D77F2740F79000E10CF6 /* Font+Settings.swift */; };
C5046526274F77C60004B812 /* SingleImageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC1820520790C930061F261 /* SingleImageCollectionViewCell.swift */; };
C5046527274F77C60004B812 /* FakeTableCellButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2A5A7920A6196700B54399 /* FakeTableCellButton.swift */; };
C5046528274F77C60004B812 /* ItemTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BE9455E2079EFCE004F9FF4 /* ItemTableViewCell.xib */; };
C5046529274F77C60004B812 /* LinkLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3C79AC21C4E58B00F699B8 /* LinkLabel.swift */; };
C504652A274F77C60004B812 /* ItemCellConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B583720212861220076121E /* ItemCellConfigurator.swift */; };
C504652B274F77C60004B812 /* ComposeViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B60CF4D2072A66C00C51258 /* ComposeViewController.xib */; };
Expand All @@ -83,7 +82,6 @@
C5046536274F77C70004B812 /* Font+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = C550D77F2740F79000E10CF6 /* Font+Settings.swift */; };
C5046537274F77C70004B812 /* SingleImageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC1820520790C930061F261 /* SingleImageCollectionViewCell.swift */; };
C5046538274F77C70004B812 /* FakeTableCellButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2A5A7920A6196700B54399 /* FakeTableCellButton.swift */; };
C5046539274F77C70004B812 /* ItemTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BE9455E2079EFCE004F9FF4 /* ItemTableViewCell.xib */; };
C504653A274F77C70004B812 /* LinkLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3C79AC21C4E58B00F699B8 /* LinkLabel.swift */; };
C504653B274F77C70004B812 /* ItemCellConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B583720212861220076121E /* ItemCellConfigurator.swift */; };
C504653C274F77C70004B812 /* ComposeViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B60CF4D2072A66C00C51258 /* ComposeViewController.xib */; };
Expand Down Expand Up @@ -365,7 +363,6 @@
5BDE18F2216A76FA001254F4 /* SettingsStoryboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SettingsStoryboard.storyboard; sourceTree = "<group>"; };
5BDE18F4216A7A47001254F4 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
5BE9455D2079EFCE004F9FF4 /* ItemTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemTableViewCell.swift; sourceTree = "<group>"; };
5BE9455E2079EFCE004F9FF4 /* ItemTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ItemTableViewCell.xib; sourceTree = "<group>"; };
5BF2DAA3228800B30055240D /* DiscoveryCategoryComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoveryCategoryComponent.swift; sourceTree = "<group>"; };
5BF2DAA5228802000055240D /* UserDefaultsMigrationComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsMigrationComponent.swift; sourceTree = "<group>"; };
5BF6637E218961AB00ABA671 /* DiscoveryCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoveryCategory.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -646,7 +643,6 @@
5BC1820520790C930061F261 /* SingleImageCollectionViewCell.swift */,
5B2A5A7920A6196700B54399 /* FakeTableCellButton.swift */,
5BE9455D2079EFCE004F9FF4 /* ItemTableViewCell.swift */,
5BE9455E2079EFCE004F9FF4 /* ItemTableViewCell.xib */,
5B3C79AC21C4E58B00F699B8 /* LinkLabel.swift */,
C55BAF28275D489D009E8A9C /* ComposeKeyboardInputView.swift */,
);
Expand Down Expand Up @@ -1224,7 +1220,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C5046539274F77C70004B812 /* ItemTableViewCell.xib in Resources */,
C504653C274F77C70004B812 /* ComposeViewController.xib in Resources */,
5BC1384721C639160040353C /* Assets.xcassets in Resources */,
);
Expand Down Expand Up @@ -1259,7 +1254,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C5046528274F77C60004B812 /* ItemTableViewCell.xib in Resources */,
C504652B274F77C60004B812 /* ComposeViewController.xib in Resources */,
BF707E742131C45600506E64 /* Localizable.strings in Resources */,
C5FA2ACE1EB4482C006DEB40 /* LaunchScreen.storyboard in Resources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<key>Icro-Next.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>5</integer>
<integer>4</integer>
</dict>
<key>Icro-Share.xcscheme_^#shared#^_</key>
<dict>
Expand Down
2 changes: 1 addition & 1 deletion Icro/ViewController/ListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ final class ListViewController: UIViewController, LoadingViewController {
tableView.separatorColor = Color.separatorColor
tableView.refreshControl = UIRefreshControl()
tableView.refreshControl?.addTarget(viewModel, action: #selector(ListViewModel.load), for: .valueChanged)
tableView.register(cellType: ItemTableViewCell.self)
tableView.registerClass(cellType: ItemTableViewCell.self)
tableView.registerClass(cellType: HostingCell<ProfileCellView>.self)
tableView.registerClass(cellType: LoadMoreTableViewCell.self)
tableView.estimatedRowHeight = UITableView.automaticDimension
Expand Down
3 changes: 1 addition & 2 deletions IcroUIKit/Configurator/ItemCellConfigurator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ public final class ItemCellConfigurator: NSObject {
self.itemNavigator.openReply(item: item)
}

cell.timeLabel.text = item.relativeDateString
cell.atUsernameLabel.text = "@" + (item.author.username ?? "")
cell.atUsernameLabel.text = "@" + (item.author.username ?? "") + "\(item.relativeDateString)"

cell.didTapMedia = { [weak self] media, index in
self?.itemNavigator.openMedia(media: media, index: index)
Expand Down
208 changes: 146 additions & 62 deletions IcroUIKit/View/ItemTableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,60 +12,67 @@ import Settings

public final class ItemTableViewCell: UITableViewCell {
enum Constants {
static let layoutSpace: CGFloat = 16.0

static let avatarImageHeightWidth = 42.0
static let actionButtonWidth: CGFloat = 120.0
}

var isFavorite: Bool = false

@IBOutlet private weak var imageHeightConstraint: NSLayoutConstraint!
let avatarImageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.isUserInteractionEnabled = true

@IBOutlet weak var avatarImageView: UIImageView! {
didSet {
avatarImageView.layer.cornerRadius = 20
avatarImageView.clipsToBounds = true
}
}
@IBOutlet weak var attributedLabel: LinkLabel! {
didSet {
attributedLabel.isOpaque = true
}
}
@IBOutlet weak var usernameLabel: UILabel! {
didSet {
usernameLabel.isOpaque = true
usernameLabel.adjustsFontForContentSizeCategory = true
usernameLabel.font = Font().name
}
}
@IBOutlet weak var atUsernameLabel: UILabel! {
didSet {
atUsernameLabel.textColor = Color.secondaryTextColor
atUsernameLabel.isOpaque = true
atUsernameLabel.adjustsFontForContentSizeCategory = true
atUsernameLabel.font = Font().username
}
}
@IBOutlet weak var timeLabel: UILabel! {
didSet {
timeLabel.textColor = Color.secondaryTextColor
timeLabel.isOpaque = true
timeLabel.adjustsFontForContentSizeCategory = true
timeLabel.font = Font().username
}
}
imageView.layer.cornerRadius = 20
imageView.clipsToBounds = true

return imageView
}()

@IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint!
let attributedLabel: LinkLabel = {
let label = LinkLabel()
label.isOpaque = true
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.isUserInteractionEnabled = true

return label
}()

let usernameLabel: UILabel = {
let label = UILabel()

label.isOpaque = true
label.adjustsFontForContentSizeCategory = true
label.font = Font().name

return label
}()

let atUsernameLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false

label.textColor = Color.secondaryTextColor
label.isOpaque = true
label.adjustsFontForContentSizeCategory = true
label.font = Font().username

return label
}()

var itemID: String?

var media = [Media]() {
didSet {
if media.count == 1 {
collectionViewHeightConstraint.constant = 240
collectionViewHeightConstraint?.constant = 240
} else if media.count > 1 {
collectionViewHeightConstraint.constant = 140
collectionViewHeightConstraint?.constant = 140
} else {
collectionViewHeightConstraint.constant = 0
collectionViewHeightConstraint?.constant = 0
}
imageCollectionView.reloadData()
}
Expand All @@ -80,32 +87,53 @@ public final class ItemTableViewCell: UITableViewCell {
return button
}()

@IBOutlet weak var imageCollectionView: UICollectionView! {
didSet {
imageCollectionView.registerClass(cellType: SingleImageCollectionViewCell.self)
imageCollectionView.delegate = self
imageCollectionView.dataSource = self
imageCollectionView.allowsSelection = true
}
}
private var collectionViewHeightConstraint: NSLayoutConstraint?
private let imageCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 10.0
layout.minimumInteritemSpacing = 10.0

let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.registerClass(cellType: SingleImageCollectionViewCell.self)
collectionView.allowsSelection = true
collectionView.layer.cornerRadius = 4.0

return collectionView
}()

private let titleHorizontalStackView: UIStackView = {
let stackView = UIStackView()
stackView.spacing = Constants.layoutSpace / 2.0
stackView.alignment = .top
stackView.axis = .horizontal
stackView.translatesAutoresizingMaskIntoConstraints = false

return stackView
}()

private let usernamesVerticalStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .fill
stackView.translatesAutoresizingMaskIntoConstraints = false

return stackView
}()

var didTapAvatar: (() -> Void)?
var didSelectAccessibilityLink :(() -> Void)?
var didTapMedia: (([Media], Int) -> Void)?
var didTapReply: (() -> Void)?

override public func prepareForReuse() {
media = []
updateAppearance()
avatarImageView.image = nil
isFavorite = false
super.prepareForReuse()
}

override public func awakeFromNib() {
super.awakeFromNib()
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

setupActionButton()
setupTitleHorizontalStackView()
setupLinkLabel()
setupCollectionView()

updateAppearance()
let avatarGestureRecognizer = UITapGestureRecognizer(target: self,
Expand All @@ -114,12 +142,70 @@ public final class ItemTableViewCell: UITableViewCell {
backgroundColor = Color.backgroundColor
}

required init?(coder: NSCoder) {
fatalError("Not supported")
}

override public func prepareForReuse() {
media = []
updateAppearance()
avatarImageView.image = nil
isFavorite = false
super.prepareForReuse()
}

private func setupActionButton() {
addSubview(actionButton)
contentView.addSubview(actionButton)
NSLayoutConstraint.activate([
actionButton.widthAnchor.constraint(equalToConstant: Constants.actionButtonWidth),
actionButton.bottomAnchor.constraint(equalTo: bottomAnchor),
actionButton.centerXAnchor.constraint(equalTo: centerXAnchor)
actionButton.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
actionButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)
])
}

private func setupCollectionView() {
imageCollectionView.delegate = self
imageCollectionView.dataSource = self

contentView.addSubview(imageCollectionView)

let heightConstraint = imageCollectionView.heightAnchor.constraint(equalToConstant: 140.0)
self.collectionViewHeightConstraint = heightConstraint

NSLayoutConstraint.activate([
heightConstraint,
imageCollectionView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Constants.layoutSpace),
imageCollectionView.bottomAnchor.constraint(equalTo: actionButton.topAnchor, constant: -Constants.layoutSpace / 4.0),
imageCollectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -Constants.layoutSpace),
imageCollectionView.topAnchor.constraint(equalTo: attributedLabel.bottomAnchor, constant: Constants.layoutSpace)
])
}

private func setupLinkLabel() {
contentView.addSubview(attributedLabel)

NSLayoutConstraint.activate([
attributedLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Constants.layoutSpace),
attributedLabel.topAnchor.constraint(equalTo: titleHorizontalStackView.bottomAnchor, constant: Constants.layoutSpace),
attributedLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -Constants.layoutSpace)
])
}

private func setupTitleHorizontalStackView() {
contentView.addSubview(titleHorizontalStackView)

titleHorizontalStackView.addArrangedSubview(avatarImageView)

usernamesVerticalStackView.addArrangedSubview(usernameLabel)
usernamesVerticalStackView.addArrangedSubview(atUsernameLabel)
titleHorizontalStackView.addArrangedSubview(usernamesVerticalStackView)

NSLayoutConstraint.activate([
titleHorizontalStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Constants.layoutSpace),
titleHorizontalStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: Constants.layoutSpace),
titleHorizontalStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -Constants.layoutSpace),
avatarImageView.heightAnchor.constraint(equalToConstant: Constants.avatarImageHeightWidth),
avatarImageView.widthAnchor.constraint(equalToConstant: Constants.avatarImageHeightWidth)
])
}

Expand Down Expand Up @@ -167,8 +253,6 @@ public final class ItemTableViewCell: UITableViewCell {
atUsernameLabel.textColor = Color.secondaryTextColor
usernameLabel.textColor = Color.textColor
usernameLabel.backgroundColor = Color.backgroundColor
timeLabel.backgroundColor = Color.backgroundColor
timeLabel.textColor = Color.secondaryTextColor
imageCollectionView.backgroundColor = Color.accentSuperLight
attributedLabel.backgroundColor = Color.backgroundColor
backgroundColor = Color.backgroundColor
Expand Down
Loading

0 comments on commit bcbc461

Please sign in to comment.