Skip to content

Commit 96f42d6

Browse files
authored
Fix SwiftKickMobile#188 physics animation visual glitch (SwiftKickMobile#189)
Fix SwiftKickMobile#188 physics animation visual glitch
1 parent f61b7d8 commit 96f42d6

File tree

10 files changed

+338
-319
lines changed

10 files changed

+338
-319
lines changed

Demo/Demo/Info.plist

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<string>UIInterfaceOrientationPortrait</string>
3636
<string>UIInterfaceOrientationLandscapeLeft</string>
3737
<string>UIInterfaceOrientationLandscapeRight</string>
38+
<string>UIInterfaceOrientationPortraitUpsideDown</string>
3839
</array>
3940
</dict>
4041
</plist>

Demo/Pods/Pods.xcodeproj/project.pbxproj

+273-269
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

SwiftMessages.xcodeproj/project.pbxproj

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
/* Begin PBXBuildFile section */
1010
220655121FAF82B600F4E00F /* MarginAdjustable+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 220655111FAF82B600F4E00F /* MarginAdjustable+Animation.swift */; };
1111
2270044B1FAFA6DD0045DDC3 /* PhysicsAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2270044A1FAFA6DD0045DDC3 /* PhysicsAnimation.swift */; };
12+
22774BA020B5EF2A00813732 /* UIEdgeInsets+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22774B9F20B5EF2A00813732 /* UIEdgeInsets+Utils.swift */; };
1213
228DF5261FACAC51004F8A39 /* errorIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 228DF5231FACAC51004F8A39 /* errorIcon.png */; };
1314
228DF5271FACAC51004F8A39 /* errorIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 228DF5241FACAC51004F8A39 /* errorIcon@2x.png */; };
1415
228DF5281FACAC51004F8A39 /* errorIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 228DF5251FACAC51004F8A39 /* errorIcon@3x.png */; };
@@ -90,6 +91,7 @@
9091
/* Begin PBXFileReference section */
9192
220655111FAF82B600F4E00F /* MarginAdjustable+Animation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MarginAdjustable+Animation.swift"; sourceTree = "<group>"; };
9293
2270044A1FAFA6DD0045DDC3 /* PhysicsAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhysicsAnimation.swift; sourceTree = "<group>"; };
94+
22774B9F20B5EF2A00813732 /* UIEdgeInsets+Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIEdgeInsets+Utils.swift"; sourceTree = "<group>"; };
9395
228DF5231FACAC51004F8A39 /* errorIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = errorIcon.png; path = Resources/errorIcon.png; sourceTree = "<group>"; };
9496
228DF5241FACAC51004F8A39 /* errorIcon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "errorIcon@2x.png"; path = "Resources/errorIcon@2x.png"; sourceTree = "<group>"; };
9597
228DF5251FACAC51004F8A39 /* errorIcon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "errorIcon@3x.png"; path = "Resources/errorIcon@3x.png"; sourceTree = "<group>"; };
@@ -252,9 +254,10 @@
252254
86AAF81D1D5549680031EE32 /* MarginAdjustable.swift */,
253255
22E307FE1E74C5B100E35893 /* AccessibleMessage.swift */,
254256
86AAF82A1D580DD70031EE32 /* Error.swift */,
255-
86DBE0031D75BE800071E51D /* Array+Utils.swift */,
256257
2298C2061EE480D000E2DDC1 /* Animator.swift */,
257258
2298C2041EE47DC900E2DDC1 /* Weak.swift */,
259+
86DBE0031D75BE800071E51D /* Array+Utils.swift */,
260+
22774B9F20B5EF2A00813732 /* UIEdgeInsets+Utils.swift */,
258261
);
259262
name = Base;
260263
sourceTree = "<group>";
@@ -477,6 +480,7 @@
477480
isa = PBXSourcesBuildPhase;
478481
buildActionMask = 2147483647;
479482
files = (
483+
22774BA020B5EF2A00813732 /* UIEdgeInsets+Utils.swift in Sources */,
480484
86BBA8FC1D5E03F100FE8F16 /* MessageView.swift in Sources */,
481485
86BBA9061D5E040C00FE8F16 /* Identifiable.swift in Sources */,
482486
86BBA9011D5E040600FE8F16 /* PassthroughWindow.swift in Sources */,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>

SwiftMessages/MarginAdjustable+Animation.swift

+13-8
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,45 @@ import UIKit
1010

1111
public extension MarginAdjustable where Self: UIView {
1212

13-
public func topAdjustment(container: UIView, context: AnimationContext) -> CGFloat {
13+
public func defaultMarginAdjustment(context: AnimationContext) -> UIEdgeInsets {
14+
return UIEdgeInsets(top: topAdjustment(context: context), left: 0, bottom: bottomAdjustment(context: context), right: 0)
15+
}
16+
17+
private func topAdjustment(context: AnimationContext) -> CGFloat {
1418
var top: CGFloat = 0
15-
top += bounceAnimationOffset
1619
if !context.safeZoneConflicts.isDisjoint(with: [.sensorNotch, .statusBar]) {
1720
if #available(iOS 11, *) {
1821
do {
1922
// To accommodate future safe areas, using a linear formula based on
2023
// two data points:
2124
// iPhone 8 - 20pt top safe area needs 0pt adjustment
2225
// iPhone X - 44pt top safe area needs -6pt adjustment
23-
top -= 6 * (container.safeAreaInsets.top - 20) / (44 - 20)
26+
top -= 6 * (safeAreaInsets.top - 20) / (44 - 20)
2427
}
2528
top += safeAreaTopOffset
2629
} else if UIApplication.shared.statusBarOrientation == .portrait || UIApplication.shared.statusBarOrientation == .portraitUpsideDown {
27-
top += statusBarOffset
30+
let frameInWindow = convert(bounds, to: window)
31+
if frameInWindow.minY == 0 {
32+
top += statusBarOffset
33+
}
2834
}
2935
} else if #available(iOS 11, *), !context.safeZoneConflicts.isDisjoint(with: .overStatusBar) {
3036
top -= safeAreaInsets.top
3137
}
3238
return top
3339
}
3440

35-
public func bottomAdjustment(container: UIView, context: AnimationContext) -> CGFloat {
41+
private func bottomAdjustment(context: AnimationContext) -> CGFloat {
3642
var bottom: CGFloat = 0
37-
bottom += bounceAnimationOffset
3843
if !context.safeZoneConflicts.isDisjoint(with: [.homeIndicator]) {
39-
if #available(iOS 11, *), container.safeAreaInsets.bottom > 0 {
44+
if #available(iOS 11, *), safeAreaInsets.bottom > 0 {
4045
do {
4146
// This adjustment was added to fix a layout issue with iPhone X in
4247
// landscape mode. Using a linear formula based on two data points to help
4348
// future proof against future safe areas:
4449
// iPhone X portrait: 34pt bottom safe area needs 0pt adjustment
4550
// iPhone X landscape: 21pt bottom safe area needs 12pt adjustment
46-
bottom -= 12 * (container.safeAreaInsets.bottom - 34) / (34 - 21)
51+
bottom -= 12 * (safeAreaInsets.bottom - 34) / (34 - 21)
4752
}
4853
bottom += safeAreaBottomOffset
4954
}

SwiftMessages/PhysicsAnimation.swift

+4-19
Original file line numberDiff line numberDiff line change
@@ -85,29 +85,14 @@ public class PhysicsAnimation: NSObject, Animator {
8585

8686
@objc public func adjustMargins() {
8787
guard let adjustable = messageView as? MarginAdjustable & UIView,
88-
let container = containerView,
8988
let context = context else { return }
90-
var top: CGFloat = 0
91-
var bottom: CGFloat = 0
92-
switch placement {
93-
case .top:
94-
top += adjustable.topAdjustment(container: container, context: context)
95-
case .bottom:
96-
bottom += adjustable.bottomAdjustment(container: container, context: context)
97-
case .center:
98-
break
99-
}
10089
adjustable.preservesSuperviewLayoutMargins = false
90+
let defaultMarginAdjustment = adjustable.defaultMarginAdjustment(context: context)
10191
if #available(iOS 11, *) {
102-
var margins = adjustable.safeAreaInsets
103-
margins.top = top
104-
margins.bottom = bottom
105-
adjustable.layoutMargins = margins
92+
adjustable.insetsLayoutMarginsFromSafeArea = false
93+
adjustable.layoutMargins = adjustable.safeAreaInsets + defaultMarginAdjustment
10694
} else {
107-
var margins = adjustable.layoutMargins
108-
margins.top = top
109-
margins.bottom = bottom
110-
adjustable.layoutMargins = margins
95+
adjustable.layoutMargins = defaultMarginAdjustment
11196
}
11297
}
11398

SwiftMessages/PhysicsPanHandler.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ open class PhysicsPanHandler {
145145
state.itemBehavior.addAngularVelocity(escapeAngularVelocity, for: messageView)
146146
state.attachmentBehavior = nil
147147
} else {
148-
animator.delegate?.panEnded(animator: animator)
149148
state.stop()
150149
self.state = nil
150+
animator.delegate?.panEnded(animator: animator)
151151
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.65, initialSpringVelocity: 0, options: .beginFromCurrentState, animations: {
152152
messageView.center = self.restingCenter ?? CGPoint(x: containerView.bounds.width / 2, y: containerView.bounds.height / 2)
153153
messageView.transform = CGAffineTransform.identity

SwiftMessages/Resources/MessageView.xib

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
33
<device id="retina4_7" orientation="portrait">
44
<adaptation id="fullscreen"/>
55
</device>
66
<dependencies>
77
<deployment version="2304" identifier="iOS"/>
8-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
99
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
1010
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
1111
</dependencies>
@@ -17,7 +17,7 @@
1717
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1818
<subviews>
1919
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="Nx9-Zd-fca">
20-
<rect key="frame" x="40" y="20" width="600" height="63"/>
20+
<rect key="frame" x="40" y="20" width="520" height="63"/>
2121
<subviews>
2222
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="😬" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1Bu-DY-qZo" userLabel="Icon label">
2323
<rect key="frame" x="0.0" y="9" width="43" height="45.5"/>
@@ -32,7 +32,7 @@
3232
<rect key="frame" x="53" y="14.5" width="33" height="34"/>
3333
</imageView>
3434
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="MKC-Mf-yZN">
35-
<rect key="frame" x="96" y="10" width="524" height="43.5"/>
35+
<rect key="frame" x="96" y="10" width="357" height="43.5"/>
3636
<subviews>
3737
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="[Title]" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8T6-4T-ytS">
3838
<rect key="frame" x="0.0" y="0.0" width="48.5" height="20.5"/>
@@ -44,7 +44,7 @@
4444
<nil key="highlightedColor"/>
4545
</label>
4646
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="[Message Body]" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dFP-4Z-N2a">
47-
<rect key="frame" x="0.0" y="25.5" width="524" height="18"/>
47+
<rect key="frame" x="0.0" y="25.5" width="112" height="18"/>
4848
<accessibility key="accessibilityConfiguration">
4949
<bool key="isElement" value="NO"/>
5050
</accessibility>
@@ -56,7 +56,7 @@
5656
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
5757
</stackView>
5858
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="252" horizontalCompressionResistancePriority="752" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VCW-IQ-FfQ">
59-
<rect key="frame" x="600" y="16.5" width="57" height="30"/>
59+
<rect key="frame" x="463" y="16.5" width="57" height="30"/>
6060
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
6161
<state key="normal" title="[Button]"/>
6262
</button>
@@ -66,7 +66,7 @@
6666
</subviews>
6767
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
6868
<constraints>
69-
<constraint firstAttribute="trailing" secondItem="Nx9-Zd-fca" secondAttribute="trailing" constant="20" id="4sW-g4-sKy"/>
69+
<constraint firstAttribute="trailingMargin" secondItem="Nx9-Zd-fca" secondAttribute="trailing" constant="20" id="4sW-g4-sKy"/>
7070
<constraint firstAttribute="bottomMargin" secondItem="Nx9-Zd-fca" secondAttribute="bottom" constant="20" id="SPZ-ev-Lj3"/>
7171
<constraint firstItem="Nx9-Zd-fca" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="topMargin" constant="20" id="UDP-8w-ZKv"/>
7272
<constraint firstItem="Nx9-Zd-fca" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leadingMargin" constant="20" id="jKx-hQ-JzW"/>

SwiftMessages/TopBottomAnimation.swift

+7-14
Original file line numberDiff line numberDiff line change
@@ -102,27 +102,20 @@ public class TopBottomAnimation: NSObject, Animator {
102102

103103
@objc public func adjustMargins() {
104104
guard let adjustable = messageView as? MarginAdjustable & UIView,
105-
let container = containerView,
106105
let context = context else { return }
107-
var top: CGFloat = 0
108-
var bottom: CGFloat = 0
106+
adjustable.preservesSuperviewLayoutMargins = false
107+
var defaultMarginAdjustment = adjustable.defaultMarginAdjustment(context: context)
109108
switch style {
110109
case .top:
111-
top = adjustable.topAdjustment(container: container, context: context)
110+
defaultMarginAdjustment.top += bounceOffset
112111
case .bottom:
113-
bottom = adjustable.bottomAdjustment(container: container, context: context)
112+
defaultMarginAdjustment.bottom += bounceOffset
114113
}
115-
adjustable.preservesSuperviewLayoutMargins = false
116114
if #available(iOS 11, *) {
117-
var margins = adjustable.safeAreaInsets
118-
margins.top = top
119-
margins.bottom = bottom
120-
adjustable.layoutMargins = margins
115+
adjustable.insetsLayoutMarginsFromSafeArea = false
116+
adjustable.layoutMargins = adjustable.safeAreaInsets + defaultMarginAdjustment
121117
} else {
122-
var margins = adjustable.layoutMargins
123-
margins.top = top
124-
margins.bottom = bottom
125-
adjustable.layoutMargins = margins
118+
adjustable.layoutMargins = defaultMarginAdjustment
126119
}
127120
}
128121

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// UIEdgeInsets+Utils.swift
3+
// SwiftMessages
4+
//
5+
// Created by Timothy Moose on 5/23/18.
6+
// Copyright © 2018 SwiftKick Mobile. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
extension UIEdgeInsets {
12+
public static func +(left: UIEdgeInsets, right: UIEdgeInsets) -> UIEdgeInsets {
13+
let topSum = left.top + right.top
14+
let leftSum = left.left + right.left
15+
let bottomSum = left.bottom + right.bottom
16+
let rightSum = left.right + right.right
17+
return UIEdgeInsets(top: topSum, left: leftSum, bottom: bottomSum, right: rightSum)
18+
}
19+
}

0 commit comments

Comments
 (0)