Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Commit 878a9d9

Browse files
authored
refactor collapse cells (#1406)
1 parent 6075edc commit 878a9d9

File tree

10 files changed

+67
-108
lines changed

10 files changed

+67
-108
lines changed

Classes/Issues/Comments/CodeBlock/IssueCommentCodeBlockCell.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import UIKit
1010
import IGListKit
1111

12-
final class IssueCommentCodeBlockCell: IssueCommentBaseCell, ListBindable, CollapsibleCell {
12+
final class IssueCommentCodeBlockCell: IssueCommentBaseCell, ListBindable {
1313

1414
static let scrollViewInset = UIEdgeInsets(
1515
top: Styles.Sizes.rowSpacing,
@@ -26,7 +26,6 @@ final class IssueCommentCodeBlockCell: IssueCommentBaseCell, ListBindable, Colla
2626

2727
let textView = AttributedStringView()
2828
let scrollView = UIScrollView()
29-
let overlay = CreateCollapsibleOverlay()
3029

3130
override init(frame: CGRect) {
3231
super.init(frame: frame)
@@ -58,7 +57,6 @@ final class IssueCommentCodeBlockCell: IssueCommentBaseCell, ListBindable, Colla
5857
width: contentView.bounds.width - inset.left - inset.right,
5958
height: scrollView.contentSize.height
6059
)
61-
LayoutCollapsible(layer: overlay, view: contentView)
6260
}
6361

6462
// MARK: ListBindable
@@ -72,10 +70,4 @@ final class IssueCommentCodeBlockCell: IssueCommentBaseCell, ListBindable, Colla
7270
textView.configureAndSizeToFit(text: viewModel.code, width: 0)
7371
}
7472

75-
// MARK: CollapsibleCell
76-
77-
func setCollapse(visible: Bool) {
78-
overlay.isHidden = !visible
79-
}
80-
8173
}

Classes/Issues/Comments/CollapsibleCell.swift

Lines changed: 0 additions & 46 deletions
This file was deleted.

Classes/Issues/Comments/Images/IssueCommentImageCell.swift

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,14 @@ protocol IssueCommentImageHeightCellDelegate: class {
1919
func imageDidFinishLoad(cell: IssueCommentImageCell, url: URL, size: CGSize)
2020
}
2121

22-
final class IssueCommentImageCell: IssueCommentBaseCell,
23-
ListBindable,
24-
CollapsibleCell {
22+
final class IssueCommentImageCell: IssueCommentBaseCell, ListBindable {
2523

2624
weak var delegate: IssueCommentImageCellDelegate?
2725
weak var heightDelegate: IssueCommentImageHeightCellDelegate?
2826

2927
let imageView = FLAnimatedImageView()
3028

3129
private let spinner = UIActivityIndicatorView(activityIndicatorStyle: .gray)
32-
private let overlay = CreateCollapsibleOverlay()
3330
private var tapGesture: UITapGestureRecognizer!
3431

3532
override init(frame: CGRect) {
@@ -59,7 +56,6 @@ CollapsibleCell {
5956

6057
override func layoutSubviews() {
6158
super.layoutSubviews()
62-
LayoutCollapsible(layer: overlay, view: contentView)
6359

6460
var frame = bounds
6561
if let size = imageView.image?.size {
@@ -105,12 +101,6 @@ CollapsibleCell {
105101
}
106102
}
107103

108-
// MARK: CollapsibleCell
109-
110-
func setCollapse(visible: Bool) {
111-
overlay.isHidden = !visible
112-
}
113-
114104
// MARK: UIGestureRecognizerDelegate
115105

116106
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
@@ -120,7 +110,7 @@ CollapsibleCell {
120110
// only start the image tap gesture when an image exists
121111
// and the tap is within the actual image's bounds
122112
guard let image = imageView.image,
123-
overlay.isHidden
113+
collapsed == false
124114
else { return false }
125115

126116
let imageSize = image.size

Classes/Issues/Comments/IssueCollapsedBodies.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ private func bodyIsCollapsible(body: Any) -> Bool {
2020
func IssueCollapsedBodies(bodies: [AnyObject], width: CGFloat) -> (AnyObject, CGFloat)? {
2121
let cap: CGFloat = 300
2222
// minimum height to collapse so expanding shows significant amount of content
23-
let minDelta = CollapseCellMinHeight * 3
23+
let minDelta = IssueCommentBaseCell.collapseCellMinHeight * 3
2424

2525
var totalHeight: CGFloat = 0
2626
for body in bodies {
@@ -34,7 +34,7 @@ func IssueCollapsedBodies(bodies: [AnyObject], width: CGFloat) -> (AnyObject, CG
3434
if bodyIsCollapsible(body: body),
3535
totalHeight > cap,
3636
totalHeight - cap > minDelta {
37-
let collapsedBodyHeight = max(cap - (totalHeight - height), CollapseCellMinHeight)
37+
let collapsedBodyHeight = max(cap - (totalHeight - height), IssueCommentBaseCell.collapseCellMinHeight)
3838
return (body, collapsedBodyHeight)
3939
}
4040
}

Classes/Issues/Comments/IssueCommentBaseCell.swift

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ protocol IssueCommentDoubleTapDelegate: class {
1414

1515
class IssueCommentBaseCell: UICollectionViewCell, UIGestureRecognizerDelegate {
1616

17+
static let collapseCellMinHeight: CGFloat = 20
18+
1719
enum BorderType {
1820
case head
1921
case neck
@@ -28,6 +30,8 @@ class IssueCommentBaseCell: UICollectionViewCell, UIGestureRecognizerDelegate {
2830

2931
private let borderLayer = CAShapeLayer()
3032
private let backgroundLayer = CAShapeLayer()
33+
private let collapseLayer = CAGradientLayer()
34+
private let collapseButton = UIButton()
3135

3236
override init(frame: CGRect) {
3337
super.init(frame: frame)
@@ -50,6 +54,26 @@ class IssueCommentBaseCell: UICollectionViewCell, UIGestureRecognizerDelegate {
5054
backgroundLayer.strokeColor = nil
5155
backgroundLayer.fillColor = UIColor.white.cgColor
5256
layer.insertSublayer(backgroundLayer, at: 0)
57+
58+
collapseLayer.isHidden = true
59+
collapseLayer.colors = [
60+
UIColor(white: 1, alpha: 0).cgColor,
61+
UIColor(white: 1, alpha: 1).cgColor
62+
]
63+
64+
collapseButton.setImage(UIImage(named: "bullets")?.withRenderingMode(.alwaysTemplate), for: .normal)
65+
collapseButton.backgroundColor = Styles.Colors.Blue.medium.color
66+
collapseButton.accessibilityTraits = UIAccessibilityTraitNone
67+
collapseButton.tintColor = .white
68+
collapseButton.titleLabel?.font = Styles.Fonts.smallTitle
69+
collapseButton.clipsToBounds = true
70+
collapseButton.isHidden = true
71+
collapseButton.contentEdgeInsets = UIEdgeInsets(top: -2, left: 8, bottom: -2, right: 8)
72+
collapseButton.imageEdgeInsets = .zero
73+
collapseButton.sizeToFit()
74+
collapseButton.layer.cornerRadius = collapseButton.bounds.height / 2
75+
collapseButton.isUserInteractionEnabled = false // allow tap to pass through to cell
76+
contentView.addSubview(collapseButton)
5377
}
5478

5579
required init?(coder aDecoder: NSCoder) {
@@ -114,6 +138,29 @@ class IssueCommentBaseCell: UICollectionViewCell, UIGestureRecognizerDelegate {
114138

115139
borderLayer.frame = self.bounds
116140
backgroundLayer.frame = self.bounds
141+
142+
if collapseLayer.isHidden == false {
143+
contentView.layer.addSublayer(collapseLayer)
144+
contentView.bringSubview(toFront: collapseButton)
145+
146+
let collapseFrame = CGRect(
147+
x: bounds.minX,
148+
y: bounds.height - IssueCommentBaseCell.collapseCellMinHeight,
149+
width: bounds.width,
150+
height: IssueCommentBaseCell.collapseCellMinHeight
151+
)
152+
153+
// disable implicit CALayer animations
154+
CATransaction.begin()
155+
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
156+
collapseLayer.frame = collapseFrame
157+
CATransaction.commit()
158+
159+
collapseButton.center = CGPoint(
160+
x: collapseFrame.width / 2,
161+
y: collapseFrame.minY + collapseButton.bounds.height / 2 - 3
162+
)
163+
}
117164
}
118165

119166
override var backgroundColor: UIColor? {
@@ -130,6 +177,14 @@ class IssueCommentBaseCell: UICollectionViewCell, UIGestureRecognizerDelegate {
130177
doubleTapDelegate?.didDoubleTap(cell: self)
131178
}
132179

180+
var collapsed: Bool = false {
181+
didSet {
182+
collapseButton.isHidden = !collapsed
183+
collapseLayer.isHidden = !collapsed
184+
setNeedsLayout()
185+
}
186+
}
187+
133188
// MARK: UIGestureRecognizerDelegate
134189

135190
func gestureRecognizer(

Classes/Issues/Comments/IssueCommentSectionController.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ IssueCommentDoubleTapDelegate {
123123
private func clearCollapseCells() {
124124
// clear any collapse state before updating so we don't have a dangling overlay
125125
for cell in collectionContext?.visibleCells(for: self) ?? [] {
126-
if let cell = cell as? CollapsibleCell {
127-
cell.setCollapse(visible: false)
126+
if let cell = cell as? IssueCommentBaseCell {
127+
cell.collapsed = false
128128
}
129129
}
130130
}
@@ -284,8 +284,8 @@ IssueCommentDoubleTapDelegate {
284284
else { fatalError("Cell not bindable") }
285285

286286
// extra config outside of bind API. applies to multiple cell types.
287-
if let cell = cell as? CollapsibleCell {
288-
cell.setCollapse(visible: collapsed && (viewModel as AnyObject) === object?.collapse?.model)
287+
if let cell = cell as? IssueCommentBaseCell {
288+
cell.collapsed = collapsed && (viewModel as AnyObject) === object?.collapse?.model
289289
}
290290

291291
// connect specific cell delegates

Classes/Issues/Comments/Quotes/IssueCommentQuoteCell.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import UIKit
1010
import IGListKit
1111

12-
final class IssueCommentQuoteCell: IssueCommentBaseCell, ListBindable, CollapsibleCell {
12+
final class IssueCommentQuoteCell: IssueCommentBaseCell, ListBindable {
1313

1414
static let borderWidth: CGFloat = 2
1515
static func inset(quoteLevel: Int) -> UIEdgeInsets {
@@ -23,7 +23,6 @@ final class IssueCommentQuoteCell: IssueCommentBaseCell, ListBindable, Collapsib
2323

2424
let textView = AttributedStringView()
2525
private var borders = [UIView]()
26-
private let overlay = CreateCollapsibleOverlay()
2726

2827
override init(frame: CGRect) {
2928
super.init(frame: frame)
@@ -37,7 +36,6 @@ final class IssueCommentQuoteCell: IssueCommentBaseCell, ListBindable, Collapsib
3736

3837
override func layoutSubviews() {
3938
super.layoutSubviews()
40-
LayoutCollapsible(layer: overlay, view: contentView)
4139
textView.reposition(width: contentView.bounds.width)
4240
for (i, border) in borders.enumerated() {
4341
border.frame = CGRect(
@@ -71,10 +69,4 @@ final class IssueCommentQuoteCell: IssueCommentBaseCell, ListBindable, Collapsib
7169
setNeedsLayout()
7270
}
7371

74-
// MARK: CollapsibleCell
75-
76-
func setCollapse(visible: Bool) {
77-
overlay.isHidden = !visible
78-
}
79-
8072
}

Classes/Issues/Comments/Summary/IssueCommentSummaryCell.swift

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import UIKit
1010
import SnapKit
1111
import IGListKit
1212

13-
final class IssueCommentSummaryCell: IssueCommentBaseCell, ListBindable, CollapsibleCell {
13+
final class IssueCommentSummaryCell: IssueCommentBaseCell, ListBindable {
1414

1515
let label = UILabel()
16-
let overlay = CreateCollapsibleOverlay()
1716

1817
override init(frame: CGRect) {
1918
super.init(frame: frame)
@@ -31,22 +30,11 @@ final class IssueCommentSummaryCell: IssueCommentBaseCell, ListBindable, Collaps
3130
fatalError("init(coder:) has not been implemented")
3231
}
3332

34-
override func layoutSubviews() {
35-
super.layoutSubviews()
36-
LayoutCollapsible(layer: overlay, view: contentView)
37-
}
38-
3933
// MARK: ListBindable
4034

4135
func bindViewModel(_ viewModel: Any) {
4236
guard let viewModel = viewModel as? IssueCommentSummaryModel else { return }
4337
label.text = "\(viewModel.summary)"
4438
}
4539

46-
// MARK: CollapsibleCell
47-
48-
func setCollapse(visible: Bool) {
49-
overlay.isHidden = !visible
50-
}
51-
5240
}

Classes/Issues/Comments/Text/IssueCommentTextCell.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import UIKit
1010
import IGListKit
1111

12-
final class IssueCommentTextCell: IssueCommentBaseCell, ListBindable, CollapsibleCell {
12+
final class IssueCommentTextCell: IssueCommentBaseCell, ListBindable {
1313

1414
static let inset = UIEdgeInsets(
1515
top: 0,
@@ -19,7 +19,6 @@ final class IssueCommentTextCell: IssueCommentBaseCell, ListBindable, Collapsibl
1919
)
2020

2121
let textView = AttributedStringView()
22-
let overlay = CreateCollapsibleOverlay()
2322

2423
override init(frame: CGRect) {
2524
super.init(frame: frame)
@@ -35,7 +34,6 @@ final class IssueCommentTextCell: IssueCommentBaseCell, ListBindable, Collapsibl
3534

3635
override func layoutSubviews() {
3736
super.layoutSubviews()
38-
LayoutCollapsible(layer: overlay, view: contentView)
3937
textView.reposition(width: contentView.bounds.width)
4038
}
4139

@@ -55,10 +53,4 @@ final class IssueCommentTextCell: IssueCommentBaseCell, ListBindable, Collapsibl
5553
textView.configureAndSizeToFit(text: viewModel, width: contentView.bounds.width)
5654
}
5755

58-
// MARK: CollapsibleCell
59-
60-
func setCollapse(visible: Bool) {
61-
overlay.isHidden = !visible
62-
}
63-
6456
}

0 commit comments

Comments
 (0)