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
|
//
// LocationSectionHeaderFooterView.swift
// MullvadVPN
//
// Created by Mojgan on 2024-01-25.
// Copyright © 2025 Mullvad VPN AB. All rights reserved.
//
import Foundation
import UIKit
class LocationSectionHeaderFooterView: UITableViewHeaderFooterView {
static let reuseIdentifier = "LocationSectionHeaderFooterView"
private let label = UILabel()
private let button = UIButton(type: .system)
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
// Configure button
button.setImage(UIImage(systemName: "ellipsis"), for: .normal)
button.tintColor = UIColor(white: 1, alpha: 0.6)
button.accessibilityIdentifier = AccessibilityIdentifier.openCustomListsMenuButton.asString
contentView.addConstrainedSubviews([label, button]) {
label.pinEdgesToSuperviewMargins(.all().excluding(.trailing))
button.pinEdgesToSuperviewMargins(.all().excluding(.leading))
button.leadingAnchor.constraint(greaterThanOrEqualTo: label.trailingAnchor, constant: 8)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(configuration: Configuration) {
var contentConfig = UIListContentConfiguration.groupedHeader()
contentConfig.text = configuration.name
contentConfig.textProperties.alignment = configuration.style.textAlignment
contentConfig.textProperties.color = configuration.style.textColor
contentConfig.textProperties.font = configuration.style.font
contentConfig.textProperties.adjustsFontForContentSizeCategory = true
contentView.backgroundColor = configuration.style.backgroundColor
directionalLayoutMargins = configuration.directionalEdgeInsets
// Apply the font and color directly to the label:
label.text = configuration.name
label.font = contentConfig.textProperties.font
label.textColor = contentConfig.textProperties.color
label.adjustsFontForContentSizeCategory = true
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.setContentCompressionResistancePriority(.required, for: .horizontal)
if let buttonAction = configuration.primaryAction {
button.isHidden = false
button.removeTarget(nil, action: nil, for: .allEvents)
button.addAction(buttonAction, for: .touchUpInside)
} else {
button.isHidden = true
}
}
}
extension LocationSectionHeaderFooterView {
struct Style: Equatable, @unchecked Sendable {
let font: UIFont
let textColor: UIColor
let textAlignment: UIListContentConfiguration.TextProperties.TextAlignment
let backgroundColor: UIColor
static let header = Style(
font: .mullvadSmallSemiBold,
textColor: .primaryTextColor,
textAlignment: .natural,
backgroundColor: .primaryColor
)
static let footer = Style(
font: .mullvadTiny,
textColor: .secondaryTextColor,
textAlignment: .center,
backgroundColor: .clear
)
}
struct Configuration {
let name: String
let style: Style
var directionalEdgeInsets = NSDirectionalEdgeInsets(top: 11, leading: 16, bottom: 11, trailing: 8)
var primaryAction: UIAction?
}
}
|