-
Notifications
You must be signed in to change notification settings - Fork 50
Expand file tree
/
Copy pathCollapsibleTableViewHeader.swift
More file actions
111 lines (85 loc) · 3.46 KB
/
CollapsibleTableViewHeader.swift
File metadata and controls
111 lines (85 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//
// CollapsibleTableViewHeader.swift
// CollapsibleTableSectionViewController
//
// Created by Yong Su on 7/20/17.
// Copyright © 2017 jeantimex. All rights reserved.
//
import UIKit
protocol CollapsibleTableViewHeaderDelegate {
func toggleSection(_ section: Int)
}
open class CollapsibleTableViewHeader: UITableViewHeaderFooterView {
var delegate: CollapsibleTableViewHeaderDelegate?
var section: Int = 0
open var titleLabel = UILabel()
open var arrowLabel = UILabel()
private func initCommon() {
// Content View
contentView.backgroundColor = UIColor(hex: 0x2E3944)
let marginGuide = contentView.layoutMarginsGuide
// Arrow label
contentView.addSubview(arrowLabel)
arrowLabel.textColor = UIColor.white
arrowLabel.translatesAutoresizingMaskIntoConstraints = false
arrowLabel.widthAnchor.constraint(equalToConstant: 12).isActive = true
arrowLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
arrowLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
arrowLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
// Title label
contentView.addSubview(titleLabel)
titleLabel.textColor = UIColor.white
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
titleLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
titleLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
titleLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
//
// Call tapHeader when tapping on this header
//
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(CollapsibleTableViewHeader.tapHeader(_:))))
}
override public init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
initCommon()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initCommon()
}
//
// Trigger toggle section when tapping on the header
//
func tapHeader(_ gestureRecognizer: UITapGestureRecognizer) {
guard let cell = gestureRecognizer.view as? CollapsibleTableViewHeader else {
return
}
_ = delegate?.toggleSection(cell.section)
}
func setCollapsed(_ collapsed: Bool) {
//
// Animate the arrow rotation (see Extensions.swf)
//
arrowLabel.rotate(collapsed ? 0.0 : .pi / 2)
}
}
extension UIColor {
convenience init(hex:Int, alpha:CGFloat = 1.0) {
self.init(
red: CGFloat((hex & 0xFF0000) >> 16) / 255.0,
green: CGFloat((hex & 0x00FF00) >> 8) / 255.0,
blue: CGFloat((hex & 0x0000FF) >> 0) / 255.0,
alpha: alpha
)
}
}
extension UIView {
func rotate(_ toValue: CGFloat, duration: CFTimeInterval = 0.2) {
let animation = CABasicAnimation(keyPath: "transform.rotation")
animation.toValue = toValue
animation.duration = duration
animation.isRemovedOnCompletion = false
animation.fillMode = kCAFillModeForwards
self.layer.add(animation, forKey: nil)
}
}