chore: remove UIView+Contraint
This commit is contained in:
parent
5ae2c44642
commit
f6be51dd0f
|
@ -132,7 +132,6 @@
|
|||
2DF75BC725D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BC625D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift */; };
|
||||
2DFAD5272616F9D300F9EE7C /* SearchViewController+Searching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFAD5262616F9D300F9EE7C /* SearchViewController+Searching.swift */; };
|
||||
2DFAD5372617010500F9EE7C /* SearchingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFAD5362617010500F9EE7C /* SearchingTableViewCell.swift */; };
|
||||
2DFF41892614A4DC00F776A4 /* UIView+Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF41882614A4DC00F776A4 /* UIView+Constraint.swift */; };
|
||||
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 */; };
|
||||
|
@ -531,7 +530,6 @@
|
|||
2DF75BC625D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedObjectContextObjectsDidChange.swift; sourceTree = "<group>"; };
|
||||
2DFAD5262616F9D300F9EE7C /* SearchViewController+Searching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchViewController+Searching.swift"; sourceTree = "<group>"; };
|
||||
2DFAD5362617010500F9EE7C /* SearchingTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingTableViewCell.swift; sourceTree = "<group>"; };
|
||||
2DFF41882614A4DC00F776A4 /* UIView+Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Constraint.swift"; sourceTree = "<group>"; };
|
||||
2E1F6A67FDF9771D3E064FDC /* Pods-Mastodon.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon_MastodonUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -1646,7 +1644,6 @@
|
|||
DB47229625F9EFAD00DA7F53 /* NSManagedObjectContext.swift */,
|
||||
2D32EAB925CB9B0500C9ED86 /* UIView.swift */,
|
||||
5DA732CB2629CEF500A92342 /* UIView+Remove.swift */,
|
||||
2DFF41882614A4DC00F776A4 /* UIView+Constraint.swift */,
|
||||
DB8AF55C25C138B7002E6C99 /* UIViewController.swift */,
|
||||
2D24E1222626ED9D00A59D4F /* UIView+Gesture.swift */,
|
||||
2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */,
|
||||
|
@ -2476,7 +2473,6 @@
|
|||
2D7867192625B77500211898 /* NotificationItem.swift in Sources */,
|
||||
DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */,
|
||||
DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */,
|
||||
2DFF41892614A4DC00F776A4 /* UIView+Constraint.swift in Sources */,
|
||||
2D5A3D0325CF8742002347D6 /* ControlContainableScrollViews.swift in Sources */,
|
||||
DB98336B25C9420100AD9700 /* APIService+App.swift in Sources */,
|
||||
DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */,
|
||||
|
|
|
@ -1,262 +0,0 @@
|
|||
//
|
||||
// UIView+Constraint.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by sxiaojian on 2021/3/31.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
enum Dimension {
|
||||
case width
|
||||
case height
|
||||
|
||||
var layoutAttribute: NSLayoutConstraint.Attribute {
|
||||
switch self {
|
||||
case .width:
|
||||
return .width
|
||||
case .height:
|
||||
return .height
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension UIView {
|
||||
|
||||
func constrain(toSuperviewEdges: UIEdgeInsets?) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return}
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
NSLayoutConstraint(item: self,
|
||||
attribute: .leading,
|
||||
relatedBy: .equal,
|
||||
toItem: view,
|
||||
attribute: .leading,
|
||||
multiplier: 1.0,
|
||||
constant: toSuperviewEdges?.left ?? 0.0),
|
||||
NSLayoutConstraint(item: self,
|
||||
attribute: .top,
|
||||
relatedBy: .equal,
|
||||
toItem: view,
|
||||
attribute: .top,
|
||||
multiplier: 1.0,
|
||||
constant: toSuperviewEdges?.top ?? 0.0),
|
||||
NSLayoutConstraint(item: view,
|
||||
attribute: .trailing,
|
||||
relatedBy: .equal,
|
||||
toItem: self,
|
||||
attribute: .trailing,
|
||||
multiplier: 1.0,
|
||||
constant: toSuperviewEdges?.right ?? 0.0),
|
||||
NSLayoutConstraint(item: view,
|
||||
attribute: .bottom,
|
||||
relatedBy: .equal,
|
||||
toItem: self,
|
||||
attribute: .bottom,
|
||||
multiplier: 1.0,
|
||||
constant: toSuperviewEdges?.bottom ?? 0.0)
|
||||
])
|
||||
}
|
||||
|
||||
func constrain(_ constraints: [NSLayoutConstraint?]) {
|
||||
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate(constraints.compactMap { $0 })
|
||||
}
|
||||
|
||||
func constraint(_ attribute: NSLayoutConstraint.Attribute, toView: UIView, constant: CGFloat?) -> NSLayoutConstraint? {
|
||||
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil}
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
return NSLayoutConstraint(item: self, attribute: attribute, relatedBy: .equal, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant ?? 0.0)
|
||||
}
|
||||
|
||||
func constraint(_ attribute: NSLayoutConstraint.Attribute, toView: UIView) -> NSLayoutConstraint? {
|
||||
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil}
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
return NSLayoutConstraint(item: self, attribute: attribute, relatedBy: .equal, toItem: toView, attribute: attribute, multiplier: 1.0, constant: 0.0)
|
||||
}
|
||||
|
||||
func constraint(_ dimension: Dimension, constant: CGFloat) -> NSLayoutConstraint? {
|
||||
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
return NSLayoutConstraint(item: self,
|
||||
attribute: dimension.layoutAttribute,
|
||||
relatedBy: .equal,
|
||||
toItem: nil,
|
||||
attribute: .notAnAttribute,
|
||||
multiplier: 1.0,
|
||||
constant: constant)
|
||||
}
|
||||
|
||||
func constrainTopCorners(sidePadding: CGFloat, topPadding: CGFloat, topLayoutGuide: UILayoutSupport) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
constraint(.leading, toView: view, constant: sidePadding),
|
||||
NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: topLayoutGuide, attribute: .bottom, multiplier: 1.0, constant: topPadding),
|
||||
constraint(.trailing, toView: view, constant: -sidePadding)
|
||||
])
|
||||
}
|
||||
|
||||
func constrainTopCorners(sidePadding: CGFloat, topPadding: CGFloat) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
constraint(.leading, toView: view, constant: sidePadding),
|
||||
constraint(.top, toView: view, constant: topPadding),
|
||||
constraint(.trailing, toView: view, constant: -sidePadding)
|
||||
])
|
||||
}
|
||||
|
||||
func constrainTopCorners(height: CGFloat) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
constraint(.leading, toView: view),
|
||||
constraint(.top, toView: view),
|
||||
constraint(.trailing, toView: view),
|
||||
constraint(.height, constant: height)
|
||||
])
|
||||
}
|
||||
|
||||
func constrainBottomCorners(sidePadding: CGFloat, bottomPadding: CGFloat) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
constraint(.leading, toView: view, constant: sidePadding),
|
||||
constraint(.bottom, toView: view, constant: -bottomPadding),
|
||||
constraint(.trailing, toView: view, constant: -sidePadding)
|
||||
])
|
||||
}
|
||||
|
||||
func constrainBottomCorners(height: CGFloat) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
constraint(.leading, toView: view),
|
||||
constraint(.bottom, toView: view),
|
||||
constraint(.trailing, toView: view),
|
||||
constraint(.height, constant: height)
|
||||
])
|
||||
}
|
||||
|
||||
func constrainLeadingCorners() {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
constraint(.top, toView: view),
|
||||
constraint(.leading, toView: view),
|
||||
constraint(.bottom, toView: view)
|
||||
])
|
||||
}
|
||||
|
||||
func constrainTrailingCorners() {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
constraint(.top, toView: view),
|
||||
constraint(.trailing, toView: view),
|
||||
constraint(.bottom, toView: view)
|
||||
])
|
||||
}
|
||||
|
||||
func constrainToCenter() {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
constraint(.centerX, toView: view),
|
||||
constraint(.centerY, toView: view)
|
||||
])
|
||||
}
|
||||
|
||||
func pin(toSize: CGSize) {
|
||||
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
widthAnchor.constraint(equalToConstant: toSize.width).priority(.required - 1),
|
||||
heightAnchor.constraint(equalToConstant: toSize.height).priority(.required - 1)
|
||||
])
|
||||
}
|
||||
|
||||
func pin(top: CGFloat?,left: CGFloat?,bottom: CGFloat?, right: CGFloat?) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
var constraints = [NSLayoutConstraint]()
|
||||
if let topConstant = top {
|
||||
constraints.append(topAnchor.constraint(equalTo: view.topAnchor, constant: topConstant))
|
||||
}
|
||||
if let leftConstant = left {
|
||||
constraints.append(leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: leftConstant))
|
||||
}
|
||||
if let bottomConstant = bottom {
|
||||
constraints.append(view.bottomAnchor.constraint(equalTo: bottomAnchor, constant: bottomConstant))
|
||||
}
|
||||
if let rightConstant = right {
|
||||
constraints.append(view.trailingAnchor.constraint(equalTo: trailingAnchor, constant: rightConstant))
|
||||
}
|
||||
constrain(constraints)
|
||||
|
||||
}
|
||||
func pinTopLeft(padding: CGFloat) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
|
||||
topAnchor.constraint(equalTo: view.topAnchor, constant: padding)])
|
||||
}
|
||||
|
||||
func pinTopLeft(top: CGFloat, left: CGFloat) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: left),
|
||||
topAnchor.constraint(equalTo: view.topAnchor, constant: top)])
|
||||
}
|
||||
|
||||
func pinTopRight(padding: CGFloat) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
view.trailingAnchor.constraint(equalTo: trailingAnchor, constant: padding),
|
||||
topAnchor.constraint(equalTo: view.topAnchor, constant: padding)])
|
||||
}
|
||||
|
||||
func pinTopRight(top: CGFloat, right: CGFloat) {
|
||||
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
view.trailingAnchor.constraint(equalTo: trailingAnchor, constant: right),
|
||||
topAnchor.constraint(equalTo: view.topAnchor, constant: top)])
|
||||
}
|
||||
|
||||
func pinTopLeft(toView: UIView, topPadding: CGFloat) {
|
||||
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
constrain([
|
||||
leadingAnchor.constraint(equalTo: toView.leadingAnchor),
|
||||
topAnchor.constraint(equalTo: toView.bottomAnchor, constant: topPadding)])
|
||||
}
|
||||
|
||||
/// Cross-fades between two views by animating their alpha then setting one or the other hidden.
|
||||
/// - parameters:
|
||||
/// - lhs: left view
|
||||
/// - rhs: right view
|
||||
/// - toRight: fade to the right view if true, fade to the left view if false
|
||||
/// - duration: animation duration
|
||||
///
|
||||
static func crossfade(_ lhs: UIView, _ rhs: UIView, toRight: Bool, duration: TimeInterval) {
|
||||
lhs.alpha = toRight ? 1.0 : 0.0
|
||||
rhs.alpha = toRight ? 0.0 : 1.0
|
||||
lhs.isHidden = false
|
||||
rhs.isHidden = false
|
||||
|
||||
UIView.animate(withDuration: duration, animations: {
|
||||
lhs.alpha = toRight ? 0.0 : 1.0
|
||||
rhs.alpha = toRight ? 1.0 : 0.0
|
||||
}, completion: { _ in
|
||||
lhs.isHidden = toRight
|
||||
rhs.isHidden = !toRight
|
||||
})
|
||||
}
|
||||
}
|
|
@ -48,8 +48,9 @@ extension NotificationViewController {
|
|||
view.backgroundColor = Asset.Colors.Background.systemBackground.color
|
||||
navigationItem.titleView = segmentControl
|
||||
segmentControl.addTarget(self, action: #selector(NotificationViewController.segmentedControlValueChanged(_:)), for: .valueChanged)
|
||||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(tableView)
|
||||
tableView.constrain([
|
||||
NSLayoutConstraint.activate([
|
||||
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
|
||||
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
|
|
|
@ -104,43 +104,60 @@ extension SearchRecommendAccountsCollectionViewCell {
|
|||
layer.cornerCurve = .continuous
|
||||
clipsToBounds = false
|
||||
applyShadow(color: Asset.Colors.Shadow.searchCard.color, alpha: 0.1, x: 0, y: 3, blur: 12, spread: 0)
|
||||
|
||||
headerImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentView.addSubview(headerImageView)
|
||||
headerImageView.pin(top: 16, left: 0, bottom: 0, right: 0)
|
||||
NSLayoutConstraint.activate([
|
||||
headerImageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
|
||||
headerImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||
headerImageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||
headerImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
||||
])
|
||||
|
||||
let containerStackView = UIStackView()
|
||||
containerStackView.axis = .vertical
|
||||
containerStackView.distribution = .fill
|
||||
containerStackView.alignment = .center
|
||||
containerStackView.spacing = 6
|
||||
containerStackView.layoutMargins = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
|
||||
containerStackView.isLayoutMarginsRelativeArrangement = true
|
||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
contentView.addSubview(containerStackView)
|
||||
NSLayoutConstraint.activate([
|
||||
containerStackView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
containerStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||
containerStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||
])
|
||||
|
||||
avatarImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentView.addSubview(avatarImageView)
|
||||
avatarImageView.pin(toSize: CGSize(width: 88, height: 88))
|
||||
avatarImageView.constrain([
|
||||
avatarImageView.constraint(.top, toView: contentView),
|
||||
avatarImageView.constraint(.centerX, toView: contentView)
|
||||
NSLayoutConstraint.activate([
|
||||
avatarImageView.widthAnchor.constraint(equalToConstant: 88),
|
||||
avatarImageView.heightAnchor.constraint(equalToConstant: 88)
|
||||
])
|
||||
containerStackView.addArrangedSubview(avatarImageView)
|
||||
containerStackView.setCustomSpacing(20, after: avatarImageView)
|
||||
displayNameLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.addArrangedSubview(displayNameLabel)
|
||||
containerStackView.setCustomSpacing(0, after: displayNameLabel)
|
||||
|
||||
contentView.addSubview(displayNameLabel)
|
||||
displayNameLabel.constrain([
|
||||
displayNameLabel.constraint(.top, toView: contentView, constant: 108),
|
||||
displayNameLabel.constraint(.leading, toView: contentView),
|
||||
displayNameLabel.constraint(.trailing, toView: contentView),
|
||||
displayNameLabel.constraint(.centerX, toView: contentView)
|
||||
])
|
||||
acctLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.addArrangedSubview(acctLabel)
|
||||
containerStackView.setCustomSpacing(7, after: acctLabel)
|
||||
|
||||
contentView.addSubview(acctLabel)
|
||||
acctLabel.constrain([
|
||||
acctLabel.constraint(.top, toView: contentView, constant: 132),
|
||||
acctLabel.constraint(.leading, toView: contentView),
|
||||
acctLabel.constraint(.trailing, toView: contentView),
|
||||
acctLabel.constraint(.centerX, toView: contentView)
|
||||
])
|
||||
|
||||
contentView.addSubview(followButton)
|
||||
followButton.pin(toSize: CGSize(width: 76, height: 24))
|
||||
followButton.constrain([
|
||||
followButton.constraint(.top, toView: contentView, constant: 159),
|
||||
followButton.constraint(.centerX, toView: contentView)
|
||||
followButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.addArrangedSubview(followButton)
|
||||
NSLayoutConstraint.activate([
|
||||
followButton.widthAnchor.constraint(equalToConstant: 76),
|
||||
followButton.heightAnchor.constraint(equalToConstant: 24)
|
||||
])
|
||||
containerStackView.addArrangedSubview(followButton)
|
||||
}
|
||||
|
||||
func config(with mastodonUser: MastodonUser) {
|
||||
displayNameLabel.text = mastodonUser.displayName.isEmpty ? mastodonUser.username : mastodonUser.displayName
|
||||
acctLabel.text = mastodonUser.acct
|
||||
acctLabel.text = "@" + mastodonUser.acct
|
||||
avatarImageView.af.setImage(
|
||||
withURL: URL(string: mastodonUser.avatar)!,
|
||||
placeholderImage: UIImage.placeholder(color: .systemFill),
|
||||
|
@ -153,7 +170,13 @@ extension SearchRecommendAccountsCollectionViewCell {
|
|||
) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
self.headerImageView.addSubview(self.visualEffectView)
|
||||
self.visualEffectView.pin(top: 0, left: 0, bottom: 0, right: 0)
|
||||
self.visualEffectView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
self.visualEffectView.topAnchor.constraint(equalTo: self.headerImageView.topAnchor),
|
||||
self.visualEffectView.leadingAnchor.constraint(equalTo: self.headerImageView.leadingAnchor),
|
||||
self.visualEffectView.trailingAnchor.constraint(equalTo: self.headerImageView.trailingAnchor),
|
||||
self.visualEffectView.bottomAnchor.constraint(equalTo: self.headerImageView.bottomAnchor)
|
||||
])
|
||||
}
|
||||
delegate?.configFollowButton(with: mastodonUser, followButton: followButton)
|
||||
followButton.publisher(for: .touchUpInside)
|
||||
|
|
|
@ -12,7 +12,6 @@ import UIKit
|
|||
class SearchRecommendTagsCollectionViewCell: UICollectionViewCell {
|
||||
let backgroundImageView: UIImageView = {
|
||||
let imageView = UIImageView()
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
return imageView
|
||||
}()
|
||||
|
||||
|
@ -20,7 +19,6 @@ class SearchRecommendTagsCollectionViewCell: UICollectionViewCell {
|
|||
let label = UILabel()
|
||||
label.textColor = .white
|
||||
label.font = .systemFont(ofSize: 20, weight: .semibold)
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.lineBreakMode = .byTruncatingTail
|
||||
return label
|
||||
}()
|
||||
|
@ -29,7 +27,6 @@ class SearchRecommendTagsCollectionViewCell: UICollectionViewCell {
|
|||
let label = UILabel()
|
||||
label.textColor = .white
|
||||
label.font = .preferredFont(forTextStyle: .body)
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
return label
|
||||
}()
|
||||
|
||||
|
@ -38,7 +35,6 @@ class SearchRecommendTagsCollectionViewCell: UICollectionViewCell {
|
|||
let image = UIImage(systemName: "flame.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .semibold))!.withRenderingMode(.alwaysTemplate)
|
||||
imageView.image = image
|
||||
imageView.tintColor = .white
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
return imageView
|
||||
}()
|
||||
|
||||
|
@ -74,17 +70,58 @@ extension SearchRecommendTagsCollectionViewCell {
|
|||
layer.borderColor = Asset.Colors.Border.searchCard.color.cgColor
|
||||
applyShadow(color: Asset.Colors.Shadow.searchCard.color, alpha: 0.1, x: 0, y: 3, blur: 12, spread: 0)
|
||||
|
||||
backgroundImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentView.addSubview(backgroundImageView)
|
||||
backgroundImageView.constrain(toSuperviewEdges: nil)
|
||||
NSLayoutConstraint.activate([
|
||||
backgroundImageView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
backgroundImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||
backgroundImageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||
backgroundImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
||||
])
|
||||
|
||||
contentView.addSubview(hashtagTitleLabel)
|
||||
hashtagTitleLabel.pin(top: 16, left: 16, bottom: nil, right: 42)
|
||||
|
||||
contentView.addSubview(peopleLabel)
|
||||
peopleLabel.pinTopLeft(top: 46, left: 16)
|
||||
let containerStackView = UIStackView()
|
||||
containerStackView.axis = .vertical
|
||||
containerStackView.distribution = .fill
|
||||
containerStackView.spacing = 6
|
||||
containerStackView.layoutMargins = UIEdgeInsets(top: 16, left: 16, bottom: 0, right: 16)
|
||||
containerStackView.isLayoutMarginsRelativeArrangement = true
|
||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentView.addSubview(containerStackView)
|
||||
NSLayoutConstraint.activate([
|
||||
containerStackView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
containerStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||
containerStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||
containerStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
||||
])
|
||||
|
||||
contentView.addSubview(flameIconView)
|
||||
flameIconView.pinTopRight(padding: 16)
|
||||
|
||||
let horizontalStackView = UIStackView()
|
||||
horizontalStackView.axis = .horizontal
|
||||
horizontalStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
horizontalStackView.distribution = .fill
|
||||
|
||||
hashtagTitleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
hashtagTitleLabel.setContentHuggingPriority(.defaultLow - 1, for: .horizontal)
|
||||
horizontalStackView.addArrangedSubview(hashtagTitleLabel)
|
||||
horizontalStackView.setContentHuggingPriority(.required - 1, for: .vertical)
|
||||
|
||||
flameIconView.translatesAutoresizingMaskIntoConstraints = false
|
||||
horizontalStackView.addArrangedSubview(flameIconView)
|
||||
|
||||
|
||||
containerStackView.addArrangedSubview(horizontalStackView)
|
||||
|
||||
let peopleHorizontalStackView = UIStackView()
|
||||
peopleHorizontalStackView.axis = .horizontal
|
||||
peopleHorizontalStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
peopleHorizontalStackView.distribution = .fill
|
||||
peopleHorizontalStackView.alignment = .top
|
||||
peopleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
peopleLabel.setContentHuggingPriority(.defaultLow - 1, for: .vertical)
|
||||
peopleHorizontalStackView.addArrangedSubview(peopleLabel)
|
||||
|
||||
containerStackView.addArrangedSubview(peopleHorizontalStackView)
|
||||
}
|
||||
|
||||
func config(with tag: Mastodon.Entity.Tag) {
|
||||
|
|
|
@ -23,8 +23,9 @@ extension SearchViewController {
|
|||
hashtagCollectionView.register(SearchRecommendTagsCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: SearchRecommendTagsCollectionViewCell.self))
|
||||
hashtagCollectionView.delegate = self
|
||||
|
||||
hashtagCollectionView.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.addArrangedSubview(hashtagCollectionView)
|
||||
hashtagCollectionView.constrain([
|
||||
NSLayoutConstraint.activate([
|
||||
hashtagCollectionView.frameLayoutGuide.heightAnchor.constraint(equalToConstant: 130)
|
||||
])
|
||||
}
|
||||
|
@ -39,8 +40,9 @@ extension SearchViewController {
|
|||
accountsCollectionView.register(SearchRecommendAccountsCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: SearchRecommendAccountsCollectionViewCell.self))
|
||||
accountsCollectionView.delegate = self
|
||||
|
||||
accountsCollectionView.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.addArrangedSubview(accountsCollectionView)
|
||||
accountsCollectionView.constrain([
|
||||
NSLayoutConstraint.activate([
|
||||
accountsCollectionView.frameLayoutGuide.heightAnchor.constraint(equalToConstant: 202)
|
||||
])
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ extension SearchViewController {
|
|||
searchingTableView.register(SearchingTableViewCell.self, forCellReuseIdentifier: String(describing: SearchingTableViewCell.self))
|
||||
searchingTableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self))
|
||||
view.addSubview(searchingTableView)
|
||||
searchingTableView.constrain([
|
||||
searchingTableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
searchingTableView.frameLayoutGuide.topAnchor.constraint(equalTo: searchBar.bottomAnchor),
|
||||
searchingTableView.frameLayoutGuide.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
|
||||
searchingTableView.frameLayoutGuide.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
|
||||
|
@ -50,18 +51,23 @@ extension SearchViewController {
|
|||
}
|
||||
|
||||
func setupSearchHeader() {
|
||||
searchHeader.addSubview(recentSearchesLabel)
|
||||
recentSearchesLabel.constrain([
|
||||
recentSearchesLabel.constraint(.leading, toView: searchHeader, constant: 16),
|
||||
recentSearchesLabel.constraint(.centerY, toView: searchHeader)
|
||||
let containerStackView = UIStackView()
|
||||
containerStackView.axis = .horizontal
|
||||
containerStackView.distribution = .fill
|
||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.layoutMargins = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
|
||||
containerStackView.isLayoutMarginsRelativeArrangement = true
|
||||
searchHeader.addSubview(containerStackView)
|
||||
NSLayoutConstraint.activate([
|
||||
containerStackView.topAnchor.constraint(equalTo: searchHeader.topAnchor),
|
||||
containerStackView.leadingAnchor.constraint(equalTo: searchHeader.leadingAnchor),
|
||||
containerStackView.trailingAnchor.constraint(equalTo: searchHeader.trailingAnchor),
|
||||
containerStackView.bottomAnchor.constraint(equalTo: searchHeader.bottomAnchor)
|
||||
])
|
||||
|
||||
searchHeader.addSubview(clearSearchHistoryButton)
|
||||
recentSearchesLabel.constrain([
|
||||
searchHeader.trailingAnchor.constraint(equalTo: clearSearchHistoryButton.trailingAnchor, constant: 16),
|
||||
clearSearchHistoryButton.constraint(.centerY, toView: searchHeader)
|
||||
])
|
||||
|
||||
recentSearchesLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.addArrangedSubview(recentSearchesLabel)
|
||||
clearSearchHistoryButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.addArrangedSubview(clearSearchHistoryButton)
|
||||
clearSearchHistoryButton.addTarget(self, action: #selector(SearchViewController.clearAction(_:)), for: .touchUpInside)
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +90,7 @@ extension SearchViewController: UITableViewDelegate {
|
|||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
guard let diffableDataSource = viewModel.searchResultDiffableDataSource else { return }
|
||||
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
|
||||
viewModel.searchResultItemDidSelected(item: item, from: self)
|
||||
|
|
|
@ -135,14 +135,16 @@ extension SearchViewController {
|
|||
func setupSearchBar() {
|
||||
searchBar.delegate = self
|
||||
view.addSubview(searchBar)
|
||||
searchBar.constrain([
|
||||
searchBar.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
searchBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
|
||||
searchBar.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
|
||||
searchBar.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
|
||||
])
|
||||
view.addSubview(statusBar)
|
||||
|
||||
statusBar.constrain([
|
||||
statusBar.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(statusBar)
|
||||
NSLayoutConstraint.activate([
|
||||
statusBar.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
statusBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
statusBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
|
@ -151,8 +153,9 @@ extension SearchViewController {
|
|||
}
|
||||
|
||||
func setupScrollView() {
|
||||
scrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(scrollView)
|
||||
scrollView.constrain([
|
||||
NSLayoutConstraint.activate([
|
||||
scrollView.frameLayoutGuide.topAnchor.constraint(equalTo: searchBar.bottomAnchor),
|
||||
scrollView.frameLayoutGuide.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
|
||||
scrollView.frameLayoutGuide.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
|
||||
|
@ -160,8 +163,9 @@ extension SearchViewController {
|
|||
scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: view.widthAnchor),
|
||||
])
|
||||
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
scrollView.addSubview(stackView)
|
||||
stackView.constrain([
|
||||
NSLayoutConstraint.activate([
|
||||
stackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
|
||||
stackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
|
||||
stackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
|
||||
|
|
|
@ -237,10 +237,10 @@ final class SearchViewModel: NSObject {
|
|||
.sink { completion in
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: recommendHashTags request fail: %s", (#file as NSString).lastPathComponent, #line, #function, error.localizedDescription)
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: recommendAccount request fail: %s", (#file as NSString).lastPathComponent, #line, #function, error.localizedDescription)
|
||||
promise(.failure(error))
|
||||
case .finished:
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: recommendHashTags request success", (#file as NSString).lastPathComponent, #line, #function)
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: recommendAccount request success", (#file as NSString).lastPathComponent, #line, #function)
|
||||
promise(.success(()))
|
||||
}
|
||||
} receiveValue: { [weak self] accounts in
|
||||
|
|
|
@ -55,19 +55,39 @@ final class SearchingTableViewCell: UITableViewCell {
|
|||
extension SearchingTableViewCell {
|
||||
private func configure() {
|
||||
backgroundColor = .clear
|
||||
selectionStyle = .none
|
||||
contentView.addSubview(_imageView)
|
||||
_imageView.pin(toSize: CGSize(width: 42, height: 42))
|
||||
_imageView.constrain([
|
||||
_imageView.constraint(.leading, toView: contentView, constant: 21),
|
||||
_imageView.constraint(.centerY, toView: contentView)
|
||||
|
||||
let containerStackView = UIStackView()
|
||||
containerStackView.axis = .horizontal
|
||||
containerStackView.distribution = .fill
|
||||
containerStackView.spacing = 12
|
||||
containerStackView.layoutMargins = UIEdgeInsets(top: 12, left: 21, bottom: 12, right: 12)
|
||||
containerStackView.isLayoutMarginsRelativeArrangement = true
|
||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentView.addSubview(containerStackView)
|
||||
NSLayoutConstraint.activate([
|
||||
containerStackView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
containerStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||
containerStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||
containerStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
||||
])
|
||||
|
||||
contentView.addSubview(_titleLabel)
|
||||
_titleLabel.pin(top: 12, left: 75, bottom: nil, right: 0)
|
||||
_imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.addArrangedSubview(_imageView)
|
||||
NSLayoutConstraint.activate([
|
||||
_imageView.widthAnchor.constraint(equalToConstant: 42),
|
||||
_imageView.heightAnchor.constraint(equalToConstant: 42),
|
||||
])
|
||||
|
||||
contentView.addSubview(_subTitleLabel)
|
||||
_subTitleLabel.pin(top: 34, left: 75, bottom: nil, right: 0)
|
||||
let textStackView = UIStackView()
|
||||
textStackView.axis = .vertical
|
||||
textStackView.distribution = .fill
|
||||
textStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
_titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
textStackView.addArrangedSubview(_titleLabel)
|
||||
_subTitleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
textStackView.addArrangedSubview(_subTitleLabel)
|
||||
|
||||
containerStackView.addArrangedSubview(textStackView)
|
||||
}
|
||||
|
||||
func config(with account: Mastodon.Entity.Account) {
|
||||
|
|
|
@ -47,14 +47,35 @@ extension SearchRecommendCollectionHeader {
|
|||
private func configure() {
|
||||
backgroundColor = .clear
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(titleLabel)
|
||||
titleLabel.pinTopLeft(top: 31, left: 16)
|
||||
|
||||
addSubview(descriptionLabel)
|
||||
descriptionLabel.constrain(toSuperviewEdges: UIEdgeInsets(top: 60, left: 16, bottom: 16, right: 16))
|
||||
let containerStackView = UIStackView()
|
||||
containerStackView.axis = .vertical
|
||||
containerStackView.layoutMargins = UIEdgeInsets(top: 31, left: 16, bottom: 16, right: 16)
|
||||
containerStackView.isLayoutMarginsRelativeArrangement = true
|
||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(containerStackView)
|
||||
NSLayoutConstraint.activate([
|
||||
containerStackView.topAnchor.constraint(equalTo: topAnchor),
|
||||
containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor)
|
||||
])
|
||||
|
||||
addSubview(seeAllButton)
|
||||
seeAllButton.pinTopRight(top: 26, right: 16)
|
||||
let horizontalStackView = UIStackView()
|
||||
horizontalStackView.axis = .horizontal
|
||||
horizontalStackView.alignment = .center
|
||||
horizontalStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
horizontalStackView.distribution = .fill
|
||||
titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
titleLabel.setContentHuggingPriority(.defaultLow - 1, for: .horizontal)
|
||||
horizontalStackView.addArrangedSubview(titleLabel)
|
||||
seeAllButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
horizontalStackView.addArrangedSubview(seeAllButton)
|
||||
|
||||
containerStackView.addArrangedSubview(horizontalStackView)
|
||||
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerStackView.addArrangedSubview(descriptionLabel)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue