chore: use stackView
This commit is contained in:
parent
ca7eb7bb12
commit
cfdd2ea670
|
@ -136,6 +136,7 @@
|
|||
5D0393902612D259007FE196 /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D03938F2612D259007FE196 /* WebViewController.swift */; };
|
||||
5D0393962612D266007FE196 /* WebViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0393952612D266007FE196 /* WebViewModel.swift */; };
|
||||
5D526FE225BE9AC400460CB9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 5D526FE125BE9AC400460CB9 /* MastodonSDK */; };
|
||||
5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DA732CB2629CEF500A92342 /* UIView+Remove.swift */; };
|
||||
5DDDF1932617442700311060 /* Mastodon+Entity+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DDDF1922617442700311060 /* Mastodon+Entity+Account.swift */; };
|
||||
5DDDF1992617447F00311060 /* Mastodon+Entity+Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DDDF1982617447F00311060 /* Mastodon+Entity+Tag.swift */; };
|
||||
5DDDF1A92617489F00311060 /* Mastodon+Entity+History.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DDDF1A82617489F00311060 /* Mastodon+Entity+History.swift */; };
|
||||
|
@ -525,6 +526,7 @@
|
|||
459EA4F43058CAB47719E963 /* Pods-Mastodon-MastodonUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
5D03938F2612D259007FE196 /* WebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewController.swift; sourceTree = "<group>"; };
|
||||
5D0393952612D266007FE196 /* WebViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewModel.swift; sourceTree = "<group>"; };
|
||||
5DA732CB2629CEF500A92342 /* UIView+Remove.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Remove.swift"; sourceTree = "<group>"; };
|
||||
5DDDF1922617442700311060 /* Mastodon+Entity+Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+Account.swift"; sourceTree = "<group>"; };
|
||||
5DDDF1982617447F00311060 /* Mastodon+Entity+Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+Tag.swift"; sourceTree = "<group>"; };
|
||||
5DDDF1A82617489F00311060 /* Mastodon+Entity+History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+History.swift"; sourceTree = "<group>"; };
|
||||
|
@ -1614,6 +1616,7 @@
|
|||
5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */,
|
||||
DB47229625F9EFAD00DA7F53 /* NSManagedObjectContext.swift */,
|
||||
2D32EAB925CB9B0500C9ED86 /* UIView.swift */,
|
||||
5DA732CB2629CEF500A92342 /* UIView+Remove.swift */,
|
||||
2DFF41882614A4DC00F776A4 /* UIView+Constraint.swift */,
|
||||
DB8AF55C25C138B7002E6C99 /* UIViewController.swift */,
|
||||
2D24E1222626ED9D00A59D4F /* UIView+Gesture.swift */,
|
||||
|
@ -2329,6 +2332,7 @@
|
|||
DB71FD3C25F8A1C500512AE1 /* APIService+Persist+PersistCache.swift in Sources */,
|
||||
2DA6055125F74407006356F9 /* AudioContainerViewModel.swift in Sources */,
|
||||
0FB3D2FE25E4CB6400AAD544 /* PickServerTitleCell.swift in Sources */,
|
||||
5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */,
|
||||
2D38F1DF25CD46A400561493 /* HomeTimelineViewController+StatusProvider.swift in Sources */,
|
||||
2D206B9225F60EA700143C56 /* UIControl.swift in Sources */,
|
||||
2D46975E25C2A54100CF4AA9 /* NSLayoutConstraint.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// UIView+Remove.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by xiaojian sun on 2021/4/16.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension UIView {
|
||||
func removeFromStackView() {
|
||||
if let stackView = self.superview as? UIStackView {
|
||||
stackView.removeArrangedSubview(self)
|
||||
}
|
||||
self.removeFromSuperview()
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ final class NotificationViewController: UIViewController, NeedsDependency {
|
|||
tableView.register(NotificationStatusTableViewCell.self, forCellReuseIdentifier: String(describing: NotificationStatusTableViewCell.self))
|
||||
tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self))
|
||||
tableView.tableFooterView = UIView()
|
||||
tableView.rowHeight = UITableView.automaticDimension
|
||||
tableView.estimatedRowHeight = UITableView.automaticDimension
|
||||
return tableView
|
||||
}()
|
||||
|
||||
|
|
|
@ -74,9 +74,7 @@ extension NotificationViewModel: NSFetchedResultsControllerDelegate {
|
|||
newSnapshot.appendItems([.bottomLoader], toSection: .main)
|
||||
}
|
||||
guard let difference = self.calculateReloadSnapshotDifference(navigationBar: navigationBar, tableView: tableView, oldSnapshot: oldSnapshot, newSnapshot: newSnapshot) else {
|
||||
diffableDataSource.apply(newSnapshot, animatingDifferences: false) {
|
||||
tableView.reloadData()
|
||||
}
|
||||
diffableDataSource.apply(newSnapshot, animatingDifferences: false)
|
||||
self.isFetchingLatestNotification.value = false
|
||||
return
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import UIKit
|
|||
|
||||
final class NotificationStatusTableViewCell: UITableViewCell {
|
||||
static let actionImageBorderWidth: CGFloat = 2
|
||||
|
||||
static let statusPadding = UIEdgeInsets(top: 50, left: 73, bottom: 24, right: 24)
|
||||
var disposeBag = Set<AnyCancellable>()
|
||||
var pollCountdownSubscription: AnyCancellable?
|
||||
|
@ -42,6 +41,11 @@ final class NotificationStatusTableViewCell: UITableViewCell {
|
|||
return view
|
||||
}()
|
||||
|
||||
let avatarContainer: UIView = {
|
||||
let view = UIView()
|
||||
return view
|
||||
}()
|
||||
|
||||
let actionLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.textColor = Asset.Colors.Label.secondary.color
|
||||
|
@ -103,53 +107,99 @@ final class NotificationStatusTableViewCell: UITableViewCell {
|
|||
|
||||
extension NotificationStatusTableViewCell {
|
||||
func configure() {
|
||||
|
||||
let container = UIView()
|
||||
container.backgroundColor = .clear
|
||||
contentView.addSubview(container)
|
||||
container.constrain([
|
||||
container.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
container.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
container.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
||||
container.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
||||
let containerStackView = UIStackView()
|
||||
containerStackView.axis = .horizontal
|
||||
containerStackView.alignment = .top
|
||||
containerStackView.spacing = 4
|
||||
containerStackView.layoutMargins = UIEdgeInsets(top: 14, left: 0, bottom: 12, right: 0)
|
||||
containerStackView.isLayoutMarginsRelativeArrangement = true
|
||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentView.addSubview(containerStackView)
|
||||
NSLayoutConstraint.activate([
|
||||
containerStackView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
containerStackView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
contentView.readableContentGuide.trailingAnchor.constraint(equalTo: containerStackView.trailingAnchor),
|
||||
contentView.bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor),
|
||||
])
|
||||
|
||||
container.addSubview(avatatImageView)
|
||||
avatatImageView.pin(toSize: CGSize(width: 35, height: 35))
|
||||
avatatImageView.pin(top: 12, left: 0, bottom: nil, right: nil)
|
||||
|
||||
container.addSubview(actionImageBackground)
|
||||
actionImageBackground.pin(toSize: CGSize(width: 24 + NotificationTableViewCell.actionImageBorderWidth, height: 24 + NotificationTableViewCell.actionImageBorderWidth))
|
||||
actionImageBackground.pin(top: 33, left: 21, bottom: nil, right: nil)
|
||||
|
||||
actionImageBackground.addSubview(actionImageView)
|
||||
actionImageView.constrainToCenter()
|
||||
|
||||
container.addSubview(nameLabel)
|
||||
nameLabel.constrain([
|
||||
nameLabel.topAnchor.constraint(equalTo: container.topAnchor, constant: 12),
|
||||
nameLabel.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 61)
|
||||
containerStackView.addArrangedSubview(avatarContainer)
|
||||
avatarContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
avatarContainer.heightAnchor.constraint(equalToConstant: 47).priority(.required - 1),
|
||||
avatarContainer.widthAnchor.constraint(equalToConstant: 47).priority(.required - 1)
|
||||
])
|
||||
|
||||
avatarContainer.addSubview(avatatImageView)
|
||||
avatatImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
avatatImageView.heightAnchor.constraint(equalToConstant: 35).priority(.required - 1),
|
||||
avatatImageView.widthAnchor.constraint(equalToConstant: 35).priority(.required - 1),
|
||||
avatatImageView.topAnchor.constraint(equalTo: avatarContainer.topAnchor),
|
||||
avatatImageView.leadingAnchor.constraint(equalTo: avatarContainer.leadingAnchor)
|
||||
])
|
||||
|
||||
avatarContainer.addSubview(actionImageBackground)
|
||||
actionImageBackground.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
actionImageBackground.heightAnchor.constraint(equalToConstant: 24 + NotificationTableViewCell.actionImageBorderWidth).priority(.required - 1),
|
||||
actionImageBackground.widthAnchor.constraint(equalToConstant: 24 + NotificationTableViewCell.actionImageBorderWidth).priority(.required - 1),
|
||||
actionImageBackground.bottomAnchor.constraint(equalTo: avatarContainer.bottomAnchor),
|
||||
actionImageBackground.trailingAnchor.constraint(equalTo: avatarContainer.trailingAnchor)
|
||||
])
|
||||
|
||||
avatarContainer.addSubview(actionImageView)
|
||||
actionImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
actionImageView.centerXAnchor.constraint(equalTo: actionImageBackground.centerXAnchor),
|
||||
actionImageView.centerYAnchor.constraint(equalTo: actionImageBackground.centerYAnchor)
|
||||
])
|
||||
|
||||
|
||||
let actionStackView = UIStackView()
|
||||
actionStackView.axis = .horizontal
|
||||
actionStackView.distribution = .fillProportionally
|
||||
actionStackView.spacing = 4
|
||||
actionStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
nameLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
actionStackView.addArrangedSubview(nameLabel)
|
||||
actionLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
actionStackView.addArrangedSubview(actionLabel)
|
||||
nameLabel.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
||||
|
||||
let statusStackView = UIStackView()
|
||||
statusStackView.axis = .vertical
|
||||
|
||||
statusStackView.distribution = .fill
|
||||
statusStackView.spacing = 4
|
||||
statusStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
statusView.translatesAutoresizingMaskIntoConstraints = false
|
||||
statusStackView.addArrangedSubview(actionStackView)
|
||||
|
||||
statusBorder.translatesAutoresizingMaskIntoConstraints = false
|
||||
statusView.translatesAutoresizingMaskIntoConstraints = false
|
||||
statusBorder.addSubview(statusView)
|
||||
NSLayoutConstraint.activate([
|
||||
statusView.topAnchor.constraint(equalTo: statusBorder.topAnchor, constant: 12),
|
||||
statusView.leadingAnchor.constraint(equalTo: statusBorder.leadingAnchor, constant: 12),
|
||||
statusBorder.bottomAnchor.constraint(equalTo: statusView.bottomAnchor, constant: 12),
|
||||
statusBorder.trailingAnchor.constraint(equalTo: statusView.trailingAnchor, constant: 12),
|
||||
])
|
||||
|
||||
container.addSubview(actionLabel)
|
||||
actionLabel.constrain([
|
||||
actionLabel.leadingAnchor.constraint(equalTo: nameLabel.trailingAnchor, constant: 4),
|
||||
actionLabel.centerYAnchor.constraint(equalTo: nameLabel.centerYAnchor),
|
||||
container.trailingAnchor.constraint(greaterThanOrEqualTo: actionLabel.trailingAnchor, constant: 4)
|
||||
])
|
||||
|
||||
statusStackView.addArrangedSubview(statusBorder)
|
||||
|
||||
containerStackView.addArrangedSubview(statusStackView)
|
||||
|
||||
statusView.contentWarningBlurContentImageView.backgroundColor = Asset.Colors.Background.secondaryGroupedSystemBackground.color
|
||||
statusView.isUserInteractionEnabled = false
|
||||
// remove item don't display
|
||||
statusView.actionToolbarContainer.isHidden = true
|
||||
statusView.avatarView.isHidden = true
|
||||
statusView.usernameLabel.isHidden = true
|
||||
|
||||
container.addSubview(statusBorder)
|
||||
statusBorder.pin(top: 40, left: 63, bottom: 14, right: 14)
|
||||
|
||||
container.addSubview(statusView)
|
||||
statusView.pin(top: NotificationStatusTableViewCell.statusPadding.top, left: NotificationStatusTableViewCell.statusPadding.left, bottom: NotificationStatusTableViewCell.statusPadding.bottom, right: NotificationStatusTableViewCell.statusPadding.right)
|
||||
statusView.actionToolbarContainer.removeFromStackView()
|
||||
// it affect stackView's height
|
||||
statusView.avatarView.removeFromStackView()
|
||||
statusView.usernameLabel.removeFromStackView()
|
||||
statusView.nameLabel.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
||||
statusView.activeTextLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
|
|
|
@ -50,6 +50,11 @@ final class NotificationTableViewCell: UITableViewCell {
|
|||
return view
|
||||
}()
|
||||
|
||||
let avatarContainer: UIView = {
|
||||
let view = UIView()
|
||||
return view
|
||||
}()
|
||||
|
||||
let actionLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.textColor = Asset.Colors.Label.secondary.color
|
||||
|
@ -86,40 +91,67 @@ final class NotificationTableViewCell: UITableViewCell {
|
|||
extension NotificationTableViewCell {
|
||||
func configure() {
|
||||
|
||||
let container = UIView()
|
||||
container.backgroundColor = .clear
|
||||
contentView.addSubview(container)
|
||||
container.constrain([
|
||||
container.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
container.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
container.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
||||
container.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
||||
let containerStackView = UIStackView()
|
||||
containerStackView.axis = .horizontal
|
||||
containerStackView.alignment = .center
|
||||
containerStackView.spacing = 4
|
||||
containerStackView.layoutMargins = UIEdgeInsets(top: 14, left: 0, bottom: 12, right: 0)
|
||||
containerStackView.isLayoutMarginsRelativeArrangement = true
|
||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentView.addSubview(containerStackView)
|
||||
NSLayoutConstraint.activate([
|
||||
containerStackView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
containerStackView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||
contentView.readableContentGuide.trailingAnchor.constraint(equalTo: containerStackView.trailingAnchor),
|
||||
contentView.bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor),
|
||||
])
|
||||
|
||||
container.addSubview(avatatImageView)
|
||||
avatatImageView.pin(toSize: CGSize(width: 35, height: 35))
|
||||
avatatImageView.pin(top: 12, left: 0, bottom: nil, right: nil)
|
||||
|
||||
container.addSubview(actionImageBackground)
|
||||
actionImageBackground.pin(toSize: CGSize(width: 24 + NotificationTableViewCell.actionImageBorderWidth, height: 24 + NotificationTableViewCell.actionImageBorderWidth))
|
||||
actionImageBackground.pin(top: 33, left: 33, bottom: nil, right: nil)
|
||||
|
||||
actionImageBackground.addSubview(actionImageView)
|
||||
actionImageView.constrainToCenter()
|
||||
|
||||
container.addSubview(nameLabel)
|
||||
nameLabel.constrain([
|
||||
nameLabel.topAnchor.constraint(equalTo: container.topAnchor, constant: 24),
|
||||
container.bottomAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 24),
|
||||
nameLabel.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 61)
|
||||
containerStackView.addArrangedSubview(avatarContainer)
|
||||
avatarContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
avatarContainer.heightAnchor.constraint(equalToConstant: 47).priority(.required - 1),
|
||||
avatarContainer.widthAnchor.constraint(equalToConstant: 47).priority(.required - 1)
|
||||
])
|
||||
|
||||
avatarContainer.addSubview(avatatImageView)
|
||||
avatatImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
avatatImageView.heightAnchor.constraint(equalToConstant: 35).priority(.required - 1),
|
||||
avatatImageView.widthAnchor.constraint(equalToConstant: 35).priority(.required - 1),
|
||||
avatatImageView.topAnchor.constraint(equalTo: avatarContainer.topAnchor),
|
||||
avatatImageView.leadingAnchor.constraint(equalTo: avatarContainer.leadingAnchor)
|
||||
])
|
||||
|
||||
avatarContainer.addSubview(actionImageBackground)
|
||||
actionImageBackground.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
actionImageBackground.heightAnchor.constraint(equalToConstant: 24 + NotificationTableViewCell.actionImageBorderWidth).priority(.required - 1),
|
||||
actionImageBackground.widthAnchor.constraint(equalToConstant: 24 + NotificationTableViewCell.actionImageBorderWidth).priority(.required - 1),
|
||||
actionImageBackground.bottomAnchor.constraint(equalTo: avatarContainer.bottomAnchor),
|
||||
actionImageBackground.trailingAnchor.constraint(equalTo: avatarContainer.trailingAnchor)
|
||||
])
|
||||
|
||||
avatarContainer.addSubview(actionImageView)
|
||||
actionImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
actionImageView.centerXAnchor.constraint(equalTo: actionImageBackground.centerXAnchor),
|
||||
actionImageView.centerYAnchor.constraint(equalTo: actionImageBackground.centerYAnchor)
|
||||
])
|
||||
|
||||
|
||||
let actionStackView = UIStackView()
|
||||
actionStackView.axis = .horizontal
|
||||
actionStackView.distribution = .fillProportionally
|
||||
actionStackView.spacing = 4
|
||||
actionStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
container.addSubview(actionLabel)
|
||||
actionLabel.constrain([
|
||||
actionLabel.leadingAnchor.constraint(equalTo: nameLabel.trailingAnchor, constant: 4),
|
||||
actionLabel.centerYAnchor.constraint(equalTo: nameLabel.centerYAnchor),
|
||||
container.trailingAnchor.constraint(greaterThanOrEqualTo: actionLabel.trailingAnchor, constant: 4)
|
||||
])
|
||||
nameLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.addArrangedSubview(nameLabel)
|
||||
actionLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.addArrangedSubview(actionLabel)
|
||||
nameLabel.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
||||
containerStackView.addArrangedSubview(actionStackView)
|
||||
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
|
|
Loading…
Reference in New Issue