Skip to content

Commit 62e12e1

Browse files
committed
Couple of fixes
1 parent c2bcb35 commit 62e12e1

8 files changed

+98
-21
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
# Change Log
22
All notable changes to this project will be documented in this file.
33

4+
## 9.0.9
5+
6+
### Fixes
7+
8+
* Fix hit testing on SwiftUI views to allow touches around the view's margins to pass through to the underlying view.
9+
* Update `KeyboardTrackingView` to continue tracking the keyboard even when not installed in the view hierarchy.
10+
411
## 9.0.8
512

613
### Changes

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,14 @@ struct DemoMessageView: View {
206206
}
207207
.multilineTextAlignment(.leading)
208208
.padding(30)
209+
// This makes the message width greedy
209210
.frame(maxWidth: .infinity)
210211
.background(.gray)
211-
// This makes a tab-style view where the bottom corners are rounded and the view's background
212-
// extends to the top edge.
212+
// This makes a tab-style view where the bottom corners are rounded and
213+
// the view's background extends to the top edge.
213214
.mask(
214-
UnevenRoundedRectangle(
215-
cornerRadii: .init(bottomLeading: 15, bottomTrailing: 15)
216-
)
215+
UnevenRoundedRectangle(bottomLeadingRadius: 15, bottomTrailingRadius: 15)
216+
// This causes the background to extend into the safe area to the screen edge.
217217
.edgesIgnoringSafeArea(.top)
218218
)
219219
}

SwiftMessages.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |spec|
22
spec.name = 'SwiftMessages'
3-
spec.version = '9.0.8'
3+
spec.version = '9.0.9'
44
spec.license = { :type => 'MIT' }
55
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
66
spec.authors = { 'Timothy Moose' => 'tim@swiftkickmobile.com' }

SwiftMessages/KeyboardTrackingView.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ open class KeyboardTrackingView: UIView {
7272

7373
private var isAutomaticallyPaused = false
7474
private var heightConstraint: NSLayoutConstraint!
75+
private var lastObservedKeyboardRect: CGRect?
7576

7677
private func postInit() {
7778
translatesAutoresizingMaskIntoConstraints = false
@@ -109,15 +110,19 @@ open class KeyboardTrackingView: UIView {
109110
isAutomaticallyPaused = false
110111
}
111112

113+
open override func layoutSubviews() {
114+
super.layoutSubviews()
115+
heightConstraint.constant = calculateHeightConstant()
116+
}
117+
112118
private func show(change: Change, _ notification: Notification) {
113119
guard !(isPaused || isAutomaticallyPaused),
114120
let userInfo = (notification as NSNotification).userInfo,
115121
let value = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
116122
willChange(change: change, userInfo: userInfo)
117123
delegate?.keyboardTrackingViewWillChange(change: change, userInfo: userInfo)
118-
let keyboardRect = value.cgRectValue
119-
let thisRect = convert(bounds, to: nil)
120-
let newHeight = max(0, thisRect.maxY - keyboardRect.minY) + topMargin
124+
lastObservedKeyboardRect = value.cgRectValue
125+
let newHeight = calculateHeightConstant()
121126
guard heightConstraint.constant != newHeight else { return }
122127
animateKeyboardChange(change: change, height: newHeight, userInfo: userInfo)
123128
}
@@ -140,4 +145,10 @@ open class KeyboardTrackingView: UIView {
140145
CATransaction.commit()
141146
}
142147
}
148+
149+
private func calculateHeightConstant() -> CGFloat {
150+
guard let keyboardRect = lastObservedKeyboardRect else { return 0 }
151+
let thisRect = convert(bounds, to: nil)
152+
return max(0, thisRect.maxY - keyboardRect.minY) + topMargin
153+
}
143154
}

SwiftMessages/MessageHostingView.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,12 @@ public class MessageHostingView<Content>: BaseView, Identifiable where Content:
3939
required init?(coder _: NSCoder) {
4040
fatalError("init(coder:) has not been implemented")
4141
}
42+
43+
public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
44+
let view = super.hitTest(point, with: event)
45+
// The rendered SwiftUI view isn't a direct child of this hosting view. SwiftUI
46+
// inserts another intermediate view that should also ignore touches.
47+
if view == self || view?.superview == self { return nil }
48+
return view
49+
}
4250
}

SwiftUIDemo/SwiftUIDemo/DemoMessage.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ import SwiftMessages
1111
struct DemoMessage: Identifiable {
1212
let title: String
1313
let body: String
14+
let style: DemoMessageView.Style
1415

1516
var id: String { title + body }
1617
}
1718

1819
extension DemoMessage: MessageViewConvertible {
1920
func asMessageView() -> DemoMessageView {
20-
DemoMessageView(message: self)
21+
DemoMessageView(message: self, style: style)
2122
}
2223
}

SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@
77

88
import SwiftUI
99

10+
// A card-style message view
1011
struct DemoMessageView: View {
1112

1213
// MARK: - API
1314

15+
enum Style {
16+
case standard
17+
case card
18+
case tab
19+
}
20+
1421
let message: DemoMessage
22+
let style: Style
23+
1524

1625
// MARK: - Variables
1726

@@ -20,21 +29,42 @@ struct DemoMessageView: View {
2029
// MARK: - Body
2130

2231
var body: some View {
32+
switch style {
33+
case .standard:
34+
content()
35+
// Mask the content and extend background into the safe area.
36+
.mask {
37+
Rectangle()
38+
.edgesIgnoringSafeArea(.top)
39+
}
40+
case .card:
41+
content()
42+
// Mask the content with a rounded rectangle
43+
.mask {
44+
RoundedRectangle(cornerRadius: 15)
45+
}
46+
// External padding around the card
47+
.padding(10)
48+
case .tab:
49+
content()
50+
// Mask the content with rounded bottom edge and extend background into the safe area.
51+
.mask {
52+
UnevenRoundedRectangle(bottomLeadingRadius: 15, bottomTrailingRadius: 15)
53+
.edgesIgnoringSafeArea(.top)
54+
}
55+
}
56+
}
57+
58+
@ViewBuilder private func content() -> some View {
2359
VStack(alignment: .leading) {
2460
Text(message.title).font(.system(size: 20, weight: .bold))
2561
Text(message.body)
2662
}
2763
.multilineTextAlignment(.leading)
64+
// Internal padding of the card
2865
.padding(30)
66+
// Greedy width
2967
.frame(maxWidth: .infinity)
3068
.background(.demoMessageBackground)
31-
// This makes a tab-style view where the bottom corners are rounded and the view's background
32-
// extends to the top edge.
33-
.mask(
34-
UnevenRoundedRectangle(
35-
cornerRadii: .init(bottomLeading: 15, bottomTrailing: 15)
36-
)
37-
.edgesIgnoringSafeArea(.top)
38-
)
3969
}
4070
}

SwiftUIDemo/SwiftUIDemo/DemoView.swift

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,30 @@ struct DemoView: View {
1313
@State var message: DemoMessage?
1414

1515
var body: some View {
16-
Button("Show message") {
17-
message = DemoMessage(title: "Demo", body: "This is a sample SwiftUI message! This content should be long enough to wrap.")
16+
VStack {
17+
Button("Show standard message") {
18+
message = DemoMessage(
19+
title: "Demo",
20+
body: "This is a sample SwiftUI card-style message! This content should be long enough to wrap.",
21+
style: .standard
22+
)
23+
}
24+
Button("Show card message") {
25+
message = DemoMessage(
26+
title: "Demo",
27+
body: "This is a sample SwiftUI card-style message! This content should be long enough to wrap.",
28+
style: .card
29+
)
30+
}
31+
Button("Show tab message") {
32+
message = DemoMessage(
33+
title: "Demo",
34+
body: "This is a sample SwiftUI card-style message! This content should be long enough to wrap.",
35+
style: .tab
36+
)
37+
}
1838
}
19-
.buttonBorderShape(.roundedRectangle(radius: 15))
39+
.buttonStyle(.bordered)
2040
.swiftMessage(message: $message)
2141
}
2242
}

0 commit comments

Comments
 (0)