Skip to content

Commit 196ffe4

Browse files
committed
Implemented dark mode support
1 parent 10363a9 commit 196ffe4

File tree

7 files changed

+131
-31
lines changed

7 files changed

+131
-31
lines changed

Example/NativeUIExample/ViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ final class ViewController: UIViewController {
5656
present(alert, animated: true)
5757

5858
case .system:
59-
let cancelAction = UIAlertAction(title: "Cancel", style: .default)
59+
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
6060
let confirmAction = UIAlertAction(title: "Confirm", style: .default)
6161

6262
let alert = UIAlertController(

Example/Podfile.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
PODS:
2-
- NativeUI (1.1.0):
3-
- NativeUI/Core (= 1.1.0)
4-
- NativeUI/Alert (1.1.0):
2+
- NativeUI (1.2.1):
3+
- NativeUI/Core (= 1.2.1)
4+
- NativeUI/Alert (1.2.1):
55
- NativeUI/Utils
6-
- NativeUI/Core (1.1.0):
6+
- NativeUI/Core (1.2.1):
77
- NativeUI/Alert
8-
- NativeUI/Utils (1.1.0)
8+
- NativeUI/Utils (1.2.1)
99

1010
DEPENDENCIES:
1111
- NativeUI (from `../`)
@@ -15,7 +15,7 @@ EXTERNAL SOURCES:
1515
:path: "../"
1616

1717
SPEC CHECKSUMS:
18-
NativeUI: d82fff2460d835a9fbd645902462e2b1d9573507
18+
NativeUI: b79f2438d4df95c876cc85c0819979521bc89367
1919

2020
PODFILE CHECKSUM: bb46d7bf1ae3b119e00a9331a12cd0a4b5cac170
2121

NativeUI.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "NativeUI"
3-
s.version = "1.2.0"
3+
s.version = "1.2.1"
44
s.summary = "Library that includes customizable replacements for native UIKit components"
55

66
s.description = <<-DESC

NativeUI.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
3A858E2A2646B8B500758898 /* SeparatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A858E292646B8B500758898 /* SeparatorView.swift */; };
1011
3AB073C22439FF7F0092DF66 /* NativeUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AB073C02439FF7F0092DF66 /* NativeUI.h */; settings = {ATTRIBUTES = (Public, ); }; };
1112
3AB073CC243A01140092DF66 /* SelectionFeedbackGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AB073CB243A01140092DF66 /* SelectionFeedbackGenerator.swift */; };
1213
3AB073D2243A017A0092DF66 /* AlertPresentationAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AB073CD243A017A0092DF66 /* AlertPresentationAnimator.swift */; };
@@ -17,6 +18,7 @@
1718
/* End PBXBuildFile section */
1819

1920
/* Begin PBXFileReference section */
21+
3A858E292646B8B500758898 /* SeparatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorView.swift; sourceTree = "<group>"; };
2022
3AB073BD2439FF7F0092DF66 /* NativeUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NativeUI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2123
3AB073C02439FF7F0092DF66 /* NativeUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeUI.h; sourceTree = "<group>"; };
2224
3AB073C12439FF7F0092DF66 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -90,6 +92,7 @@
9092
isa = PBXGroup;
9193
children = (
9294
3AB073CB243A01140092DF66 /* SelectionFeedbackGenerator.swift */,
95+
3A858E292646B8B500758898 /* SeparatorView.swift */,
9396
);
9497
path = Utils;
9598
sourceTree = "<group>";
@@ -177,6 +180,7 @@
177180
3AB073D5243A017A0092DF66 /* AlertView.swift in Sources */,
178181
3AB073D6243A017A0092DF66 /* AlertViewController.swift in Sources */,
179182
3AB073D3243A017A0092DF66 /* Alert.swift in Sources */,
183+
3A858E2A2646B8B500758898 /* SeparatorView.swift in Sources */,
180184
3AB073CC243A01140092DF66 /* SelectionFeedbackGenerator.swift in Sources */,
181185
3AB073D4243A017A0092DF66 /* AlertActionSequenceView.swift in Sources */,
182186
3AB073D2243A017A0092DF66 /* AlertPresentationAnimator.swift in Sources */,

NativeUI/Sources/Alert/AlertActionSequenceView.swift

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ protocol AlertActionSequenceViewDelegate: AnyObject {
1515
struct AlertActionSequenceViewModel {
1616
let actions: [Alert.Action]
1717
let disabledTintColor: UIColor?
18-
let separatorColor: UIColor
19-
let separatorWidth: CGFloat
2018
}
2119

2220
final class AlertActionSequenceView: UIControl {
@@ -122,7 +120,7 @@ final class AlertActionSequenceView: UIControl {
122120
}
123121

124122
for action in viewModel.actions.dropFirst() {
125-
let separator = makeButtonSeparatorView(viewModel: viewModel)
123+
let separator = makeButtonSeparatorView()
126124
stackView.addArrangedSubview(separator)
127125

128126
let actionView = makeActionView(for: action, disabledTintColor: viewModel.disabledTintColor)
@@ -167,11 +165,10 @@ final class AlertActionSequenceView: UIControl {
167165
}
168166
}
169167

170-
private func makeButtonSeparatorView(viewModel: AlertActionSequenceViewModel) -> UIView {
171-
let separatorView = UIView()
168+
private func makeButtonSeparatorView() -> UIView {
169+
let separatorView = SeparatorView()
172170
separatorView.translatesAutoresizingMaskIntoConstraints = false
173-
separatorView.backgroundColor = viewModel.separatorColor
174-
separatorView.widthAnchor.constraint(equalToConstant: viewModel.separatorWidth).isActive = true
171+
separatorView.axis = .vertical
175172
return separatorView
176173
}
177174

NativeUI/Sources/Alert/AlertView.swift

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,18 @@ final class AlertView: UIView {
1818

1919
weak var delegate: AlertViewDelegate?
2020

21-
private let separatorColor: UIColor = UIColor.lightGray
22-
2321
// MARK: - Subviews
2422

2523
// MARK: Blur
2624

2725
private lazy var blurView: UIVisualEffectView = {
28-
let blurEffect = UIBlurEffect(style: .extraLight)
26+
let blurStyle: UIBlurEffect.Style
27+
if #available(iOS 13, *) {
28+
blurStyle = .systemMaterial
29+
} else {
30+
blurStyle = .extraLight
31+
}
32+
let blurEffect = UIBlurEffect(style: blurStyle)
2933

3034
let effectView = UIVisualEffectView(effect: blurEffect)
3135
effectView.translatesAutoresizingMaskIntoConstraints = false
@@ -80,9 +84,9 @@ final class AlertView: UIView {
8084
}()
8185

8286
private lazy var contentSeparatorView: UIView = {
83-
let separatorView = UIView()
84-
separatorView.backgroundColor = separatorColor
87+
let separatorView = SeparatorView()
8588
separatorView.translatesAutoresizingMaskIntoConstraints = false
89+
separatorView.axis = .horizontal
8690
return separatorView
8791
}()
8892

@@ -144,10 +148,6 @@ final class AlertView: UIView {
144148
actionsStackView.addArrangedSubview(contentSeparatorView)
145149
actionsStackView.addArrangedSubview(actionSequenceView)
146150

147-
NSLayoutConstraint.activate([
148-
contentSeparatorView.heightAnchor.constraint(equalToConstant: Layout.separatorThickness)
149-
])
150-
151151
[titleLabel, messageLabel].forEach {
152152
$0.setContentHuggingPriority(.required, for: .vertical)
153153
$0.setContentCompressionResistancePriority(.required, for: .vertical)
@@ -208,9 +208,7 @@ final class AlertView: UIView {
208208
if !viewModel.actions.isEmpty {
209209
let actionsViewModel = AlertActionSequenceViewModel(
210210
actions: viewModel.actions,
211-
disabledTintColor: viewModel.disabledTintColor,
212-
separatorColor: separatorColor,
213-
separatorWidth: Layout.separatorThickness
211+
disabledTintColor: viewModel.disabledTintColor
214212
)
215213
actionSequenceView.setup(viewModel: actionsViewModel)
216214
}
@@ -222,10 +220,6 @@ final class AlertView: UIView {
222220

223221
private enum Layout {
224222

225-
static var separatorThickness: CGFloat {
226-
return 1.0 / UIScreen.main.scale
227-
}
228-
229223
enum Content {
230224
static let top: CGFloat = 20
231225
static let bottom: CGFloat = 20
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//
2+
// SeparatorView.swift
3+
// NativeUI
4+
//
5+
// Created by Anton Poltoratskyi on 08.05.2021.
6+
// Copyright © 2021 Anton Poltoratskyi. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
final class SeparatorView: UIView {
12+
13+
enum Axis {
14+
case vertical
15+
case horizontal
16+
}
17+
18+
var axis: Axis = .horizontal {
19+
didSet {
20+
updateAxis()
21+
}
22+
}
23+
24+
// MARK: - Subviews
25+
26+
private lazy var contentView: UIView = {
27+
let contentView = UIView()
28+
contentView.translatesAutoresizingMaskIntoConstraints = false
29+
30+
let lightThemeColor = UIColor.lightGray
31+
let darkThemeColor = UIColor.darkGray
32+
33+
if #available(iOS 13.0, *) {
34+
contentView.backgroundColor = UIColor { traitCollection in
35+
switch traitCollection.userInterfaceStyle {
36+
case .light, .unspecified:
37+
return lightThemeColor
38+
case .dark:
39+
return darkThemeColor
40+
@unknown default:
41+
return lightThemeColor
42+
}
43+
}
44+
} else {
45+
contentView.backgroundColor = lightThemeColor
46+
}
47+
48+
addSubview(contentView)
49+
50+
return contentView
51+
}()
52+
53+
private lazy var heightConstraint = heightAnchor.constraint(equalToConstant: separatorThickness(for: traitCollection))
54+
private lazy var widthConstraint = widthAnchor.constraint(equalToConstant: separatorThickness(for: traitCollection))
55+
56+
// MARK: - Init
57+
58+
override init(frame: CGRect) {
59+
super.init(frame: frame)
60+
initialize()
61+
}
62+
63+
required init?(coder: NSCoder) {
64+
super.init(coder: coder)
65+
initialize()
66+
}
67+
68+
// MARK: - Base Setup
69+
70+
private func initialize() {
71+
setContentHuggingPriority(.required, for: .vertical)
72+
setContentHuggingPriority(.required, for: .horizontal)
73+
setContentCompressionResistancePriority(.required, for: .vertical)
74+
setContentCompressionResistancePriority(.required, for: .horizontal)
75+
76+
NSLayoutConstraint.activate([
77+
contentView.leadingAnchor.constraint(equalTo: leadingAnchor),
78+
contentView.trailingAnchor.constraint(equalTo: trailingAnchor),
79+
contentView.topAnchor.constraint(equalTo: topAnchor),
80+
contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
81+
])
82+
83+
updateAxis()
84+
}
85+
86+
private func updateAxis() {
87+
switch axis {
88+
case .horizontal:
89+
widthConstraint.isActive = false
90+
heightConstraint.isActive = true
91+
case .vertical:
92+
widthConstraint.isActive = true
93+
heightConstraint.isActive = false
94+
}
95+
}
96+
97+
private func separatorThickness(for traitCollection: UITraitCollection?) -> CGFloat {
98+
return 1.0 / max(1, traitCollection?.displayScale ?? 1)
99+
}
100+
101+
public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
102+
heightConstraint.constant = separatorThickness(for: traitCollection)
103+
widthConstraint.constant = separatorThickness(for: traitCollection)
104+
}
105+
}

0 commit comments

Comments
 (0)