Skip to content

Instantly share code, notes, and snippets.

@Jyrno42
Last active March 13, 2019 15:37
Show Gist options
  • Save Jyrno42/de6cbc417d3f829a49b20db3775409cc to your computer and use it in GitHub Desktop.
Save Jyrno42/de6cbc417d3f829a49b20db3775409cc to your computer and use it in GitHub Desktop.
diff --git a/node_modules/react-native-navigation/ReactNativeNavigation.podspec b/node_modules/react-native-navigation/ReactNativeNavigation.podspec
index 61ae3ac..11b5e54 100644
--- a/node_modules/react-native-navigation/ReactNativeNavigation.podspec
+++ b/node_modules/react-native-navigation/ReactNativeNavigation.podspec
@@ -19,5 +19,6 @@ Pod::Spec.new do |s|
s.exclude_files = "lib/ios/ReactNativeNavigationTests/**/*.*", "lib/ios/OCMock/**/*.*"
s.dependency 'React'
+ s.dependency 'DeckTransition'
s.frameworks = 'UIKit'
end
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/anim/ModalAnimator.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/anim/ModalAnimator.java
index 6f6d483..a8505ff 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/anim/ModalAnimator.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/anim/ModalAnimator.java
@@ -16,14 +16,14 @@ public class ModalAnimator extends BaseAnimator {
super(context);
}
- public void show(View view, AnimationOptions show, AnimatorListenerAdapter listener) {
- animator = show.getAnimation(view, getDefaultPushAnimation(view));
+ public void show(View view, View otherView, AnimationOptions show, AnimatorListenerAdapter listener) {
+ animator = show.getAnimation(view, otherView, getDefaultPushAnimation(view), false);
animator.addListener(listener);
animator.start();
}
- public void dismiss(View view, AnimationOptions dismiss, AnimatorListenerAdapter listener) {
- animator = dismiss.getAnimation(view, getDefaultPopAnimation(view));
+ public void dismiss(View view, View otherView, AnimationOptions dismiss, AnimatorListenerAdapter listener) {
+ animator = dismiss.getAnimation(view, otherView, getDefaultPopAnimation(view), true);
animator.addListener(listener);
animator.start();
}
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/parse/AnimationOptions.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/parse/AnimationOptions.java
index 704b18c..e4e8ded 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/parse/AnimationOptions.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/parse/AnimationOptions.java
@@ -1,17 +1,23 @@
package com.reactnativenavigation.parse;
-
import android.animation.Animator;
import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.res.Resources;
import android.util.Property;
+import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.View;
import com.reactnativenavigation.parse.params.Bool;
+import com.reactnativenavigation.parse.params.Fraction;
import com.reactnativenavigation.parse.params.NullBool;
+import com.reactnativenavigation.parse.params.NullFraction;
import com.reactnativenavigation.parse.params.NullText;
import com.reactnativenavigation.parse.params.Text;
import com.reactnativenavigation.parse.parsers.BoolParser;
+import com.reactnativenavigation.parse.parsers.FractionParser;
import com.reactnativenavigation.parse.parsers.TextParser;
+import com.reactnativenavigation.R;
import org.json.JSONObject;
@@ -39,6 +45,18 @@ public class AnimationOptions {
case "waitForRender":
options.waitForRender = BoolParser.parse(json, key);
break;
+ case "enableDeck":
+ options.enableDeck = BoolParser.parse(json, key);
+ break;
+ case "deckPresentDuration":
+ options.deckPresentDuration = FractionParser.parse(json, key);
+ break;
+ case "deckDismissDuration":
+ options.deckDismissDuration = FractionParser.parse(json, key);
+ break;
+ case "enableDeckSwipeToDismiss":
+ // Swipe-to-dismiss is currently only supported on IOS
+ break;
default:
options.valueOptions.add(ValueAnimationOptions.parse(json.optJSONObject(key), getAnimProp(key)));
}
@@ -50,12 +68,18 @@ public class AnimationOptions {
public Text id = new NullText();
public Bool enabled = new NullBool();
public Bool waitForRender = new NullBool();
+ public Bool enableDeck = new NullBool();
+ public Fraction deckPresentDuration = new NullFraction();
+ public Fraction deckDismissDuration = new NullFraction();
private HashSet<ValueAnimationOptions> valueOptions = new HashSet<>();
void mergeWith(AnimationOptions other) {
if (other.id.hasValue()) id = other.id;
if (other.enabled.hasValue()) enabled = other.enabled;
if (other.waitForRender.hasValue()) waitForRender = other.waitForRender;
+ if (other.enableDeck.hasValue()) enableDeck = other.enableDeck;
+ if (other.deckPresentDuration.hasValue()) deckPresentDuration = other.deckPresentDuration;
+ if (other.deckDismissDuration.hasValue()) deckDismissDuration = other.deckDismissDuration;
if (!other.valueOptions.isEmpty()) valueOptions = other.valueOptions;
}
@@ -63,11 +87,14 @@ public class AnimationOptions {
if (!id.hasValue()) id = defaultOptions.id;
if (!enabled.hasValue()) enabled = defaultOptions.enabled;
if (!waitForRender.hasValue()) waitForRender = defaultOptions.waitForRender;
+ if (!enableDeck.hasValue()) enableDeck = defaultOptions.enableDeck;
+ if (!deckPresentDuration.hasValue()) deckPresentDuration = defaultOptions.deckPresentDuration;
+ if (!deckDismissDuration.hasValue()) deckDismissDuration = defaultOptions.deckDismissDuration;
if (valueOptions.isEmpty()) valueOptions = defaultOptions.valueOptions;
}
public boolean hasValue() {
- return id.hasValue() || enabled.hasValue() || waitForRender.hasValue();
+ return id.hasValue() || enabled.hasValue() || waitForRender.hasValue() || enableDeck.hasValue() || deckPresentDuration.hasValue() || deckDismissDuration.hasValue();
}
public AnimatorSet getAnimation(View view) {
@@ -75,12 +102,78 @@ public class AnimationOptions {
}
public AnimatorSet getAnimation(View view, AnimatorSet defaultAnimation) {
+ return getAnimation(view, null, defaultAnimation, false);
+ }
+
+ public AnimatorSet getAnimation(View view, View otherView, AnimatorSet defaultAnimation, boolean isReverse) {
if (!hasAnimation()) return defaultAnimation;
AnimatorSet animationSet = new AnimatorSet();
List<Animator> animators = new ArrayList<>();
for (ValueAnimationOptions options : valueOptions) {
animators.add(options.getAnimation(view));
}
+
+ if (enableDeck.isTrue()) {
+ int duration = (int) ((deckPresentDuration.hasValue() ? deckPresentDuration.get() : 0.3f) * 1000);
+ float screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
+
+ float topMargin = screenHeight * 0.05f;
+ float fromY = isReverse ? topMargin : screenHeight;
+ float toY = isReverse ? screenHeight : topMargin;
+
+ ObjectAnimator modalPosition = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, fromY, toY);
+ modalPosition.setStartDelay(0);
+ modalPosition.setDuration(duration);
+ modalPosition.setInterpolator(new AccelerateDecelerateInterpolator()); // Mimic DeckTransition interpolator - curveEaseOut
+
+ animators.add(modalPosition);
+
+ if (otherView != null) {
+ float toScale = isReverse ? 1.0f : 0.95f;
+
+ ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(otherView, View.SCALE_X, toScale);
+ scaleXAnimator.setStartDelay(0);
+ scaleXAnimator.setDuration(duration);
+ scaleXAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); // Mimic DeckTransition interpolator - curveEaseOut
+ animators.add(scaleXAnimator);
+
+ ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(otherView, View.SCALE_Y, toScale);
+ scaleYAnimator.setStartDelay(0);
+ scaleYAnimator.setDuration(duration);
+ scaleYAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); // Mimic DeckTransition interpolator - curveEaseOut
+ animators.add(scaleYAnimator);
+
+ Object viewTag = view.getTag(R.id.deckTransitionDepth);
+ Object otherTag = otherView.getTag(R.id.deckTransitionDepth);
+
+ int stackDepth = otherTag != null ? (int) otherTag : 0;
+
+ // Set the shown/hidden views stack depth
+ if (isReverse) {
+ view.setTag(R.id.deckTransitionDepth, 0);
+ } else {
+ view.setTag(R.id.deckTransitionDepth, stackDepth + 1);
+ }
+
+ // Reset position of other view when new Depth is zero
+ boolean resetOtherPosition = isReverse && stackDepth <= 0;
+
+ if (isReverse) {
+ ObjectAnimator otherPos = ObjectAnimator.ofFloat(otherView, View.TRANSLATION_Y, !resetOtherPosition ? topMargin : 0.0f);
+ otherPos.setStartDelay(0);
+ otherPos.setDuration(duration);
+ otherPos.setInterpolator(new AccelerateDecelerateInterpolator()); // Mimic DeckTransition interpolator - curveEaseOut
+ animators.add(otherPos);
+ } else {
+ ObjectAnimator otherPos = ObjectAnimator.ofFloat(otherView, View.TRANSLATION_Y, 0.0f);
+ otherPos.setStartDelay(0);
+ otherPos.setDuration(duration);
+ otherPos.setInterpolator(new AccelerateDecelerateInterpolator()); // Mimic DeckTransition interpolator - curveEaseOut
+ animators.add(otherPos);
+ }
+ }
+ }
+
animationSet.playTogether(animators);
return animationSet;
}
@@ -108,6 +201,6 @@ public class AnimationOptions {
}
public boolean hasAnimation() {
- return !valueOptions.isEmpty();
+ return !valueOptions.isEmpty() || enableDeck.isTrue();
}
}
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java
index 68fd5fa..01977ec 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java
@@ -2,6 +2,9 @@ package com.reactnativenavigation.viewcontrollers.modal;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.graphics.Color;
+import android.graphics.drawable.GradientDrawable;
import android.support.annotation.Nullable;
import android.view.ViewGroup;
@@ -39,6 +42,7 @@ public class ModalPresenter {
listener.onError("Can not show modal before activity is created");
return;
}
+
Options options = toAdd.resolveCurrentOptions(defaultOptions);
toAdd.setWaitForRender(options.animations.showModal.waitForRender);
modalsLayout.addView(toAdd.getView());
@@ -58,7 +62,7 @@ public class ModalPresenter {
}
private void animateShow(ViewController toAdd, ViewController toRemove, CommandListener listener, Options options) {
- animator.show(toAdd.getView(), options.animations.showModal, new AnimatorListenerAdapter() {
+ animator.show(toAdd.getView(), toRemove.getView(), options.animations.showModal, new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
onShowModalEnd(toAdd, toRemove, listener);
@@ -78,10 +82,11 @@ public class ModalPresenter {
listener.onError("Can not dismiss modal before activity is created");
return;
}
+
if (toAdd != null) toAdd.attachView(toAdd == root ? rootLayout : modalsLayout, 0);
Options options = toDismiss.resolveCurrentOptions(defaultOptions);
if (options.animations.dismissModal.enabled.isTrueOrUndefined()) {
- animator.dismiss(toDismiss.getView(), options.animations.dismissModal, new AnimatorListenerAdapter() {
+ animator.dismiss(toDismiss.getView(), toAdd != null ? toAdd.getView() : root.getView(), options.animations.dismissModal, new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
onDismissEnd(toDismiss, listener);
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/res/values/ids.xml b/node_modules/react-native-navigation/lib/android/app/src/main/res/values/ids.xml
index af0bc25..6ed653a 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/res/values/ids.xml
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/res/values/ids.xml
@@ -3,4 +3,5 @@
<item name="react_root_view" type="id"/>
<item name="fragment_screen_content" type="id"/>
<item name="topBarBackgroundComponent" type="id"/>
+ <item name="deckTransitionDepth" type="id"/>
</resources>
\ No newline at end of file
diff --git a/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalAnimatorMock.java b/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalAnimatorMock.java
index 8d8536d..aca4c16 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalAnimatorMock.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalAnimatorMock.java
@@ -14,7 +14,7 @@ public class ModalAnimatorMock extends ModalAnimator {
}
@Override
- public void show(View view, AnimationOptions show, AnimatorListenerAdapter listener) {
+ public void show(View view, View otherView, AnimationOptions show, AnimatorListenerAdapter listener) {
try {
listener.onAnimationStart(null);
Thread.sleep(10);
@@ -25,7 +25,7 @@ public class ModalAnimatorMock extends ModalAnimator {
}
@Override
- public void dismiss(View view, AnimationOptions dismiss, AnimatorListenerAdapter listener) {
+ public void dismiss(View view, View otherView, AnimationOptions dismiss, AnimatorListenerAdapter listener) {
try {
listener.onAnimationStart(null);
Thread.sleep(10);
diff --git a/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java b/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java
index 0326631..7d2c2f5 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java
@@ -85,6 +85,7 @@ public class ModalPresenterTest extends BaseTest {
uut.showModal(modal1, root, listener);
verify(animator, times(0)).show(
eq(modal1.getView()),
+ eq(null),
eq(modal1.options.animations.showModal),
any()
);
@@ -104,7 +105,7 @@ public class ModalPresenterTest extends BaseTest {
@Test
public void showModal_previousModalIsRemovedFromHierarchy() {
- uut.showModal(modal1, null, new CommandListenerAdapter() {
+ uut.showModal(modal1, root, new CommandListenerAdapter() {
@Override
public void onSuccess(String childId) {
uut.showModal(modal2, modal1, new CommandListenerAdapter() {
@@ -121,11 +122,12 @@ public class ModalPresenterTest extends BaseTest {
@Test
public void showModal_animatesByDefault() {
- uut.showModal(modal1, null, new CommandListenerAdapter() {
+ uut.showModal(modal1, root, new CommandListenerAdapter() {
@Override
public void onSuccess(String childId) {
verify(animator, times(1)).show(
eq(modal1.getView()),
+ eq(root.getView()),
eq(modal1.options.animations.showModal),
any()
);
@@ -155,7 +157,7 @@ public class ModalPresenterTest extends BaseTest {
disableShowModalAnimation(modal1);
uut.showModal(modal1, root, new CommandListenerAdapter());
- uut.dismissModal(modal1, root, root, new CommandListenerAdapter() {
+ uut.dismissModal(modal1, null, root, new CommandListenerAdapter() {
@Override
public void onSuccess(String childId) {
verify(modal1, times(1)).onViewDisappear();
@@ -163,7 +165,7 @@ public class ModalPresenterTest extends BaseTest {
}
});
- verify(animator).dismiss(eq(modal1.getView()), any(), any());
+ verify(animator).dismiss(any(), any(), any(), any());
}
@Test
@@ -187,7 +189,7 @@ public class ModalPresenterTest extends BaseTest {
uut.dismissModal(modal1, root, root, new CommandListenerAdapter());
verify(modal1, times(1)).onViewDisappear();
verify(modal1, times(1)).destroy();
- verify(animator, times(0)).dismiss(any(), eq(modal1.options.animations.dismissModal), any());
+ verify(animator, times(0)).dismiss(any(), any(), eq(modal1.options.animations.dismissModal), any());
}
@Test
diff --git a/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest.java b/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest.java
index 1238cbc..a2bc6d5 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest.java
@@ -199,7 +199,7 @@ public class ModalStackTest extends BaseTest {
Options resolvedOptions = new Options();
when(modal2.resolveCurrentOptions(defaultOptions)).then(invocation -> resolvedOptions);
uut.showModal(modal1, root, new CommandListenerAdapter());
- uut.showModal(modal2, root, new CommandListenerAdapter());
+ uut.showModal(modal2, modal1, new CommandListenerAdapter());
ViewGroup view1 = modal1.getView();
ViewGroup view2 = modal2.getView();
@@ -207,8 +207,8 @@ public class ModalStackTest extends BaseTest {
uut.dismissAllModals(root, Options.EMPTY, listener);
verify(presenter).dismissModal(eq(modal2), eq(root), eq(root), any());
verify(listener).onSuccess(modal2.getId());
- verify(animator, times(0)).dismiss(eq(view1), eq(modal1.options.animations.dismissModal), any());
- verify(animator).dismiss(eq(view2), eq(resolvedOptions.animations.dismissModal), any());
+ verify(animator, times(0)).dismiss(eq(view1), eq(root.getView()), eq(modal1.options.animations.dismissModal), any());
+ verify(animator).dismiss(eq(view2), eq(root.getView()), eq(resolvedOptions.animations.dismissModal), any());
assertThat(uut.size()).isEqualTo(0);
}
diff --git a/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java b/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java
index aaf890c..9408e37 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java
@@ -384,8 +384,10 @@ public class NavigatorTest extends BaseTest {
@Test
public void findController_modal() {
- uut.showModal(child1, new CommandListenerAdapter());
- assertThat(uut.findController(child1.getId())).isEqualTo(child1);
+ ViewController root = spy(child1);
+ uut.setRoot(root, new CommandListenerAdapter(), reactInstanceManager);
+ uut.showModal(child2, new CommandListenerAdapter());
+ assertThat(uut.findController(child2.getId())).isEqualTo(child2);
}
@NonNull
diff --git a/node_modules/react-native-navigation/lib/dist/interfaces/Options.d.ts b/node_modules/react-native-navigation/lib/dist/interfaces/Options.d.ts
index 408210e..b90bcd9 100644
--- a/node_modules/react-native-navigation/lib/dist/interfaces/Options.d.ts
+++ b/node_modules/react-native-navigation/lib/dist/interfaces/Options.d.ts
@@ -736,6 +736,24 @@ export interface OptionsAnimationSeparate {
* Configure animations for the content (Screen)
*/
content?: OptionsAnimationPropertiesId;
+ /**
+ * Disable/Enable deck transition [Default: false]
+ *
+ * Warning: IOS only
+ */
+ enableDeck?: boolean;
+ /**
+ * Disable/Enable swipe to dismiss interaction [Default: true]
+ */
+ enableDeckSwipeToDismiss?: boolean;
+ /**
+ * Duration of the appear animation in seconds [Default: 0.3]
+ */
+ deckPresentDuration?: boolean;
+ /**
+ * Duration of the dismiss animation in seconds [Default: 0.3]
+ */
+ deckDismissDuration?: boolean;
}
export interface OptionsAnimations {
/**
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/CHANGELOG.md b/node_modules/react-native-navigation/lib/ios/DeckTransition/CHANGELOG.md
new file mode 100644
index 0000000..7629ee3
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/CHANGELOG.md
@@ -0,0 +1 @@
+see https://github.com/HarshilShah/DeckTransition/blob/2.1.0/CHANGELOG.md
\ No newline at end of file
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/DeckTransition.podspec b/node_modules/react-native-navigation/lib/ios/DeckTransition/DeckTransition.podspec
new file mode 100755
index 0000000..8c6eaec
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/DeckTransition.podspec
@@ -0,0 +1,19 @@
+Pod::Spec.new do |spec|
+ spec.name = 'DeckTransition'
+ spec.version = '2.1.0'
+ spec.summary = 'An attempt to recreate the iOS 10 now playing transition'
+ spec.description = <<-DESC
+ DeckTransition is an attempt to recreate the iOS 10 Apple Music now playing and iMessage App Store transition.
+ DESC
+ spec.homepage = 'https://github.com/HarshilShah/DeckTransition'
+ spec.license = { :type => 'MIT', :file => 'LICENSE' }
+ spec.author = { 'Harshil Shah' => 'harshilshah1910@me.com' }
+ spec.social_media_url = 'https://twitter.com/harshilshah1910'
+
+ spec.source = { :git => 'https://github.com/HarshilShah/DeckTransition.git', :tag => spec.version.to_s }
+ spec.source_files = 'Source/**/*.{h,swift}'
+
+ spec.framework = 'UIKit'
+ spec.ios.deployment_target = '9.0'
+
+end
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/DeckTransition.xcodeproj/project.pbxproj b/node_modules/react-native-navigation/lib/ios/DeckTransition/DeckTransition.xcodeproj/project.pbxproj
new file mode 100755
index 0000000..eb3e62d
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/DeckTransition.xcodeproj/project.pbxproj
@@ -0,0 +1,563 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ D93F1CA21EAEDB6E009A7474 /* DeckTransition.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D93F1C981EAEDB6E009A7474 /* DeckTransition.framework */; };
+ D93F1CA71EAEDB6E009A7474 /* DeckTransitionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93F1CA61EAEDB6E009A7474 /* DeckTransitionTests.swift */; };
+ D93F1CA91EAEDB6E009A7474 /* DeckTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = D93F1C9B1EAEDB6E009A7474 /* DeckTransition.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ E83354EE1F35EC3B00D1FB23 /* RoundedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E83354ED1F35EC3B00D1FB23 /* RoundedView.swift */; };
+ E8473CC81F698D3700852FE3 /* ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8473CC71F698D3700852FE3 /* ManualLayout.swift */; };
+ E85798101F34D63200C6CABE /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = E857980F1F34D63200C6CABE /* Constants.swift */; };
+ E8683D2C1F3462E800EB9FCC /* DeckTransition.podspec in Resources */ = {isa = PBXBuildFile; fileRef = E8683D281F3462E800EB9FCC /* DeckTransition.podspec */; };
+ E8683D2D1F3462E800EB9FCC /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = E8683D291F3462E800EB9FCC /* LICENSE */; };
+ E8683D2E1F3462E800EB9FCC /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = E8683D2A1F3462E800EB9FCC /* CHANGELOG.md */; };
+ E8683D2F1F3462E800EB9FCC /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = E8683D2B1F3462E800EB9FCC /* README.md */; };
+ E8683D821F34471B005C7E9A /* DeckPresentingAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8683D811F34471B005C7E9A /* DeckPresentingAnimationController.swift */; };
+ E8683D861F34478A005C7E9A /* DeckTransitioningDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8683D851F34478A005C7E9A /* DeckTransitioningDelegate.swift */; };
+ E8683D881F344793005C7E9A /* DeckSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8683D871F344793005C7E9A /* DeckSegue.swift */; };
+ E8683D8A1F34479E005C7E9A /* DeckPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8683D891F34479E005C7E9A /* DeckPresentationController.swift */; };
+ E8683D8C1F3447A5005C7E9A /* DeckDismissingAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8683D8B1F3447A5005C7E9A /* DeckDismissingAnimationController.swift */; };
+ E87B47241F6E793D004AA6C7 /* CornerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87B47231F6E793D004AA6C7 /* CornerView.swift */; };
+ E87B47261F6E7983004AA6C7 /* CGRect+Corners.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87B47251F6E7983004AA6C7 /* CGRect+Corners.swift */; };
+ E87B47281F6E799D004AA6C7 /* Corner.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87B47271F6E799D004AA6C7 /* Corner.swift */; };
+ E87B472A1F6E79C0004AA6C7 /* CGRect+InitWithCorner.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87B47291F6E79C0004AA6C7 /* CGRect+InitWithCorner.swift */; };
+ E8B20A8F1FD84CE400648C9A /* UIViewController+IsPresentedWithDeck.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B20A8E1FD84CE400648C9A /* UIViewController+IsPresentedWithDeck.swift */; };
+ E8B20A921FD84F1500648C9A /* DeckSnapshotUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B20A911FD84F1500648C9A /* DeckSnapshotUpdater.swift */; };
+ E8B271621FD7E117009883B2 /* DeckTransitionViewControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B271611FD7E117009883B2 /* DeckTransitionViewControllerProtocol.swift */; };
+ E8B271641FD7E145009883B2 /* UIViewController+DeckTransitionViewControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B271631FD7E145009883B2 /* UIViewController+DeckTransitionViewControllerProtocol.swift */; };
+ E8B271661FD7E208009883B2 /* ScrollViewDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B271651FD7E208009883B2 /* ScrollViewDetector.swift */; };
+ E8B271681FD7E20F009883B2 /* ScrollViewUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B271671FD7E20F009883B2 /* ScrollViewUpdater.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ D93F1CA31EAEDB6E009A7474 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D93F1C8F1EAEDB6E009A7474 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = D93F1C971EAEDB6E009A7474;
+ remoteInfo = DeckTransition;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ D93F1C981EAEDB6E009A7474 /* DeckTransition.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DeckTransition.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ D93F1C9B1EAEDB6E009A7474 /* DeckTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeckTransition.h; sourceTree = "<group>"; };
+ D93F1C9C1EAEDB6E009A7474 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ D93F1CA11EAEDB6E009A7474 /* DeckTransitionTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DeckTransitionTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ D93F1CA61EAEDB6E009A7474 /* DeckTransitionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeckTransitionTests.swift; sourceTree = "<group>"; };
+ D93F1CA81EAEDB6E009A7474 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ E83354ED1F35EC3B00D1FB23 /* RoundedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedView.swift; sourceTree = "<group>"; };
+ E8473CC71F698D3700852FE3 /* ManualLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualLayout.swift; sourceTree = "<group>"; };
+ E857980F1F34D63200C6CABE /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
+ E8683D281F3462E800EB9FCC /* DeckTransition.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DeckTransition.podspec; sourceTree = SOURCE_ROOT; };
+ E8683D291F3462E800EB9FCC /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = SOURCE_ROOT; };
+ E8683D2A1F3462E800EB9FCC /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = SOURCE_ROOT; };
+ E8683D2B1F3462E800EB9FCC /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; };
+ E8683D811F34471B005C7E9A /* DeckPresentingAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeckPresentingAnimationController.swift; sourceTree = "<group>"; };
+ E8683D851F34478A005C7E9A /* DeckTransitioningDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeckTransitioningDelegate.swift; sourceTree = "<group>"; };
+ E8683D871F344793005C7E9A /* DeckSegue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeckSegue.swift; sourceTree = "<group>"; };
+ E8683D891F34479E005C7E9A /* DeckPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeckPresentationController.swift; sourceTree = "<group>"; };
+ E8683D8B1F3447A5005C7E9A /* DeckDismissingAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeckDismissingAnimationController.swift; sourceTree = "<group>"; };
+ E87B47231F6E793D004AA6C7 /* CornerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerView.swift; sourceTree = "<group>"; };
+ E87B47251F6E7983004AA6C7 /* CGRect+Corners.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGRect+Corners.swift"; sourceTree = "<group>"; };
+ E87B47271F6E799D004AA6C7 /* Corner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Corner.swift; sourceTree = "<group>"; };
+ E87B47291F6E79C0004AA6C7 /* CGRect+InitWithCorner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGRect+InitWithCorner.swift"; sourceTree = "<group>"; };
+ E8B20A8E1FD84CE400648C9A /* UIViewController+IsPresentedWithDeck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+IsPresentedWithDeck.swift"; sourceTree = "<group>"; };
+ E8B20A911FD84F1500648C9A /* DeckSnapshotUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeckSnapshotUpdater.swift; sourceTree = "<group>"; };
+ E8B271611FD7E117009883B2 /* DeckTransitionViewControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeckTransitionViewControllerProtocol.swift; sourceTree = "<group>"; };
+ E8B271631FD7E145009883B2 /* UIViewController+DeckTransitionViewControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+DeckTransitionViewControllerProtocol.swift"; sourceTree = "<group>"; };
+ E8B271651FD7E208009883B2 /* ScrollViewDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollViewDetector.swift; sourceTree = "<group>"; };
+ E8B271671FD7E20F009883B2 /* ScrollViewUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollViewUpdater.swift; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D93F1C941EAEDB6E009A7474 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D93F1C9E1EAEDB6E009A7474 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D93F1CA21EAEDB6E009A7474 /* DeckTransition.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ D93F1C8E1EAEDB6E009A7474 = {
+ isa = PBXGroup;
+ children = (
+ E8683D301F3462EF00EB9FCC /* Metadata */,
+ D93F1C9A1EAEDB6E009A7474 /* Source */,
+ D93F1CA51EAEDB6E009A7474 /* Tests */,
+ D93F1C991EAEDB6E009A7474 /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ D93F1C991EAEDB6E009A7474 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D93F1C981EAEDB6E009A7474 /* DeckTransition.framework */,
+ D93F1CA11EAEDB6E009A7474 /* DeckTransitionTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ D93F1C9A1EAEDB6E009A7474 /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ E8683D871F344793005C7E9A /* DeckSegue.swift */,
+ E8683D851F34478A005C7E9A /* DeckTransitioningDelegate.swift */,
+ E8683D891F34479E005C7E9A /* DeckPresentationController.swift */,
+ E8683D811F34471B005C7E9A /* DeckPresentingAnimationController.swift */,
+ E8683D8B1F3447A5005C7E9A /* DeckDismissingAnimationController.swift */,
+ E8B20A911FD84F1500648C9A /* DeckSnapshotUpdater.swift */,
+ E8B271611FD7E117009883B2 /* DeckTransitionViewControllerProtocol.swift */,
+ E8B271651FD7E208009883B2 /* ScrollViewDetector.swift */,
+ E8B271671FD7E20F009883B2 /* ScrollViewUpdater.swift */,
+ E857980F1F34D63200C6CABE /* Constants.swift */,
+ E8473CC71F698D3700852FE3 /* ManualLayout.swift */,
+ E828C6F61F6E7C2200BD04F5 /* RoundedView */,
+ E8B20A901FD84D0900648C9A /* Extensions */,
+ E8683D801F344638005C7E9A /* Supporting Files */,
+ );
+ path = Source;
+ sourceTree = "<group>";
+ };
+ D93F1CA51EAEDB6E009A7474 /* Tests */ = {
+ isa = PBXGroup;
+ children = (
+ D93F1CA61EAEDB6E009A7474 /* DeckTransitionTests.swift */,
+ D93F1CA81EAEDB6E009A7474 /* Info.plist */,
+ );
+ path = Tests;
+ sourceTree = "<group>";
+ };
+ E828C6F61F6E7C2200BD04F5 /* RoundedView */ = {
+ isa = PBXGroup;
+ children = (
+ E83354ED1F35EC3B00D1FB23 /* RoundedView.swift */,
+ E87B47231F6E793D004AA6C7 /* CornerView.swift */,
+ E87B47271F6E799D004AA6C7 /* Corner.swift */,
+ );
+ path = RoundedView;
+ sourceTree = "<group>";
+ };
+ E8683D301F3462EF00EB9FCC /* Metadata */ = {
+ isa = PBXGroup;
+ children = (
+ E8683D2B1F3462E800EB9FCC /* README.md */,
+ E8683D2A1F3462E800EB9FCC /* CHANGELOG.md */,
+ E8683D281F3462E800EB9FCC /* DeckTransition.podspec */,
+ E8683D291F3462E800EB9FCC /* LICENSE */,
+ );
+ name = Metadata;
+ sourceTree = "<group>";
+ };
+ E8683D801F344638005C7E9A /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ D93F1C9B1EAEDB6E009A7474 /* DeckTransition.h */,
+ D93F1C9C1EAEDB6E009A7474 /* Info.plist */,
+ );
+ path = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ E8B20A901FD84D0900648C9A /* Extensions */ = {
+ isa = PBXGroup;
+ children = (
+ E8B20A8E1FD84CE400648C9A /* UIViewController+IsPresentedWithDeck.swift */,
+ E8B271631FD7E145009883B2 /* UIViewController+DeckTransitionViewControllerProtocol.swift */,
+ E87B47291F6E79C0004AA6C7 /* CGRect+InitWithCorner.swift */,
+ E87B47251F6E7983004AA6C7 /* CGRect+Corners.swift */,
+ );
+ path = Extensions;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ D93F1C951EAEDB6E009A7474 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D93F1CA91EAEDB6E009A7474 /* DeckTransition.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ D93F1C971EAEDB6E009A7474 /* DeckTransition */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D93F1CAC1EAEDB6E009A7474 /* Build configuration list for PBXNativeTarget "DeckTransition" */;
+ buildPhases = (
+ D93F1C931EAEDB6E009A7474 /* Sources */,
+ D93F1C941EAEDB6E009A7474 /* Frameworks */,
+ D93F1C951EAEDB6E009A7474 /* Headers */,
+ D93F1C961EAEDB6E009A7474 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DeckTransition;
+ productName = DeckTransition;
+ productReference = D93F1C981EAEDB6E009A7474 /* DeckTransition.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+ D93F1CA01EAEDB6E009A7474 /* DeckTransitionTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D93F1CAF1EAEDB6E009A7474 /* Build configuration list for PBXNativeTarget "DeckTransitionTests" */;
+ buildPhases = (
+ D93F1C9D1EAEDB6E009A7474 /* Sources */,
+ D93F1C9E1EAEDB6E009A7474 /* Frameworks */,
+ D93F1C9F1EAEDB6E009A7474 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ D93F1CA41EAEDB6E009A7474 /* PBXTargetDependency */,
+ );
+ name = DeckTransitionTests;
+ productName = DeckTransitionTests;
+ productReference = D93F1CA11EAEDB6E009A7474 /* DeckTransitionTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ D93F1C8F1EAEDB6E009A7474 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0830;
+ LastUpgradeCheck = 1000;
+ ORGANIZATIONNAME = "Harshil Shah";
+ TargetAttributes = {
+ D93F1C971EAEDB6E009A7474 = {
+ CreatedOnToolsVersion = 8.3.2;
+ DevelopmentTeam = BM5Y87HJ2F;
+ LastSwiftMigration = 1000;
+ ProvisioningStyle = Automatic;
+ };
+ D93F1CA01EAEDB6E009A7474 = {
+ CreatedOnToolsVersion = 8.3.2;
+ ProvisioningStyle = Automatic;
+ };
+ };
+ };
+ buildConfigurationList = D93F1C921EAEDB6E009A7474 /* Build configuration list for PBXProject "DeckTransition" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = D93F1C8E1EAEDB6E009A7474;
+ productRefGroup = D93F1C991EAEDB6E009A7474 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D93F1C971EAEDB6E009A7474 /* DeckTransition */,
+ D93F1CA01EAEDB6E009A7474 /* DeckTransitionTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ D93F1C961EAEDB6E009A7474 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E8683D2D1F3462E800EB9FCC /* LICENSE in Resources */,
+ E8683D2E1F3462E800EB9FCC /* CHANGELOG.md in Resources */,
+ E8683D2F1F3462E800EB9FCC /* README.md in Resources */,
+ E8683D2C1F3462E800EB9FCC /* DeckTransition.podspec in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D93F1C9F1EAEDB6E009A7474 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D93F1C931EAEDB6E009A7474 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E8B20A921FD84F1500648C9A /* DeckSnapshotUpdater.swift in Sources */,
+ E8B271661FD7E208009883B2 /* ScrollViewDetector.swift in Sources */,
+ E83354EE1F35EC3B00D1FB23 /* RoundedView.swift in Sources */,
+ E8683D821F34471B005C7E9A /* DeckPresentingAnimationController.swift in Sources */,
+ E87B47281F6E799D004AA6C7 /* Corner.swift in Sources */,
+ E87B47261F6E7983004AA6C7 /* CGRect+Corners.swift in Sources */,
+ E8683D881F344793005C7E9A /* DeckSegue.swift in Sources */,
+ E8B271641FD7E145009883B2 /* UIViewController+DeckTransitionViewControllerProtocol.swift in Sources */,
+ E8B271681FD7E20F009883B2 /* ScrollViewUpdater.swift in Sources */,
+ E8473CC81F698D3700852FE3 /* ManualLayout.swift in Sources */,
+ E87B47241F6E793D004AA6C7 /* CornerView.swift in Sources */,
+ E8683D8A1F34479E005C7E9A /* DeckPresentationController.swift in Sources */,
+ E8B271621FD7E117009883B2 /* DeckTransitionViewControllerProtocol.swift in Sources */,
+ E85798101F34D63200C6CABE /* Constants.swift in Sources */,
+ E8B20A8F1FD84CE400648C9A /* UIViewController+IsPresentedWithDeck.swift in Sources */,
+ E8683D861F34478A005C7E9A /* DeckTransitioningDelegate.swift in Sources */,
+ E87B472A1F6E79C0004AA6C7 /* CGRect+InitWithCorner.swift in Sources */,
+ E8683D8C1F3447A5005C7E9A /* DeckDismissingAnimationController.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D93F1C9D1EAEDB6E009A7474 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D93F1CA71EAEDB6E009A7474 /* DeckTransitionTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ D93F1CA41EAEDB6E009A7474 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = D93F1C971EAEDB6E009A7474 /* DeckTransition */;
+ targetProxy = D93F1CA31EAEDB6E009A7474 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ D93F1CAA1EAEDB6E009A7474 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Debug;
+ };
+ D93F1CAB1EAEDB6E009A7474 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Release;
+ };
+ D93F1CAD1EAEDB6E009A7474 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_IDENTITY = "";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = BM5Y87HJ2F;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ INFOPLIST_FILE = "$(SRCROOT)/Source/Supporting Files/Info.plist";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = org.harshilShah.DeckTransition;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 4.2;
+ };
+ name = Debug;
+ };
+ D93F1CAE1EAEDB6E009A7474 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_IDENTITY = "";
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = BM5Y87HJ2F;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ INFOPLIST_FILE = "$(SRCROOT)/Source/Supporting Files/Info.plist";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = org.harshilShah.DeckTransition;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_VERSION = 4.2;
+ };
+ name = Release;
+ };
+ D93F1CB01EAEDB6E009A7474 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = Tests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.harshilshah.DeckTransitionTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ D93F1CB11EAEDB6E009A7474 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = Tests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.harshilshah.DeckTransitionTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ D93F1C921EAEDB6E009A7474 /* Build configuration list for PBXProject "DeckTransition" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D93F1CAA1EAEDB6E009A7474 /* Debug */,
+ D93F1CAB1EAEDB6E009A7474 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D93F1CAC1EAEDB6E009A7474 /* Build configuration list for PBXNativeTarget "DeckTransition" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D93F1CAD1EAEDB6E009A7474 /* Debug */,
+ D93F1CAE1EAEDB6E009A7474 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D93F1CAF1EAEDB6E009A7474 /* Build configuration list for PBXNativeTarget "DeckTransitionTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D93F1CB01EAEDB6E009A7474 /* Debug */,
+ D93F1CB11EAEDB6E009A7474 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = D93F1C8F1EAEDB6E009A7474 /* Project object */;
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/DeckTransition.xcodeproj/xcshareddata/xcschemes/DeckTransition.xcscheme b/node_modules/react-native-navigation/lib/ios/DeckTransition/DeckTransition.xcodeproj/xcshareddata/xcschemes/DeckTransition.xcscheme
new file mode 100755
index 0000000..5716704
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/DeckTransition.xcodeproj/xcshareddata/xcschemes/DeckTransition.xcscheme
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "1000"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "D93F1C971EAEDB6E009A7474"
+ BuildableName = "DeckTransition.framework"
+ BlueprintName = "DeckTransition"
+ ReferencedContainer = "container:DeckTransition.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "D93F1CA01EAEDB6E009A7474"
+ BuildableName = "DeckTransitionTests.xctest"
+ BlueprintName = "DeckTransitionTests"
+ ReferencedContainer = "container:DeckTransition.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "D93F1C971EAEDB6E009A7474"
+ BuildableName = "DeckTransition.framework"
+ BlueprintName = "DeckTransition"
+ ReferencedContainer = "container:DeckTransition.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "D93F1C971EAEDB6E009A7474"
+ BuildableName = "DeckTransition.framework"
+ BlueprintName = "DeckTransition"
+ ReferencedContainer = "container:DeckTransition.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "D93F1C971EAEDB6E009A7474"
+ BuildableName = "DeckTransition.framework"
+ BlueprintName = "DeckTransition"
+ ReferencedContainer = "container:DeckTransition.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/LICENSE b/node_modules/react-native-navigation/lib/ios/DeckTransition/LICENSE
new file mode 100755
index 0000000..fdb450b
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2016 Harshil Shah <harshilshah1910@me.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/README.md b/node_modules/react-native-navigation/lib/ios/DeckTransition/README.md
new file mode 100644
index 0000000..2985c0c
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/README.md
@@ -0,0 +1 @@
+see https://github.com/HarshilShah/DeckTransition/blob/2.1.0/README.md
\ No newline at end of file
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Constants.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Constants.swift
new file mode 100755
index 0000000..d22f518
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Constants.swift
@@ -0,0 +1,27 @@
+//
+// Constants.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 04/08/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+struct Constants {
+
+ /// Default duration for present and dismiss animations when the user hasn't
+ /// specified one
+ static let defaultAnimationDuration: TimeInterval = 0.3
+
+ /// The corner radius applied to the presenting and presented view
+ /// controllers's views
+ static let cornerRadius: CGFloat = 8
+
+ /// The alpha value of the presented view controller's view
+ static let alphaForPresentingView: CGFloat = 0.8
+
+ /// As best as I can tell using my iPhone and a bunch of iOS UI templates I
+ /// came across online, 8 points is the distance between the top edges of
+ /// the presented and the presenting views
+ static let insetForPresentedView: CGFloat = 8
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckDismissingAnimationController.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckDismissingAnimationController.swift
new file mode 100755
index 0000000..befb99d
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckDismissingAnimationController.swift
@@ -0,0 +1,58 @@
+//
+// DeckDismissingAnimationController.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 15/10/16.
+// Copyright © 2016 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+final class DeckDismissingAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
+
+ // MARK: - Private variables
+
+ private let duration: TimeInterval?
+
+ // MARK: - Initializers
+
+ init(duration: TimeInterval?) {
+ self.duration = duration
+ }
+
+ // MARK: - UIViewControllerAnimatedTransitioning
+
+ func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
+
+ /// The presentedViewController throughout this library refers to the
+ /// card view controller which is presented in the Deck style, and so
+ /// for consistency, even through it's the view controller that we are
+ /// transitioning `.from` in the context of the dismissal animation and
+ /// should thus be the `presentingViewController`, it's referred to as
+ /// the `presentedViewController` here
+
+ guard let presentedViewController = transitionContext.viewController(forKey: .from) else {
+ return
+ }
+
+ let containerView = transitionContext.containerView
+
+ let offscreenFrame = CGRect(x: 0, y: containerView.bounds.height, width: containerView.bounds.width, height: containerView.bounds.height)
+
+ UIView.animate(
+ withDuration: transitionDuration(using: transitionContext),
+ delay: 0,
+ options: .curveEaseOut,
+ animations: {
+ presentedViewController.view.frame = offscreenFrame
+ }, completion: { finished in
+ transitionContext.completeTransition(finished)
+ })
+ }
+
+ func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
+ return duration ?? Constants.defaultAnimationDuration
+ }
+
+}
+
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckPresentationController.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckPresentationController.swift
new file mode 100755
index 0000000..4d72e2f
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckPresentationController.swift
@@ -0,0 +1,647 @@
+//
+// DeckPresentationController.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 15/10/16.
+// Copyright © 2016 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+final class DeckPresentationController: UIPresentationController, UIGestureRecognizerDelegate, DeckSnapshotUpdater {
+
+ // MARK: - Internal variables
+
+ /// The presentation controller holds a strong reference to the
+ /// transitioning delegate because `UIViewController.transitioningDelegate`
+ /// is a weak property, and thus the `DeckTransitioningDelegate` would be
+ /// unallocated right after the presentation animation.
+ ///
+ /// Since the transitioningDelegate only vends the presentation controller
+ /// object and does not hold a reference to it, there is no issue of a
+ /// circular dependency here.
+ var transitioningDelegate: DeckTransitioningDelegate?
+
+ // MARK: - Private variables
+
+ private var isSwipeToDismissGestureEnabled = true
+ private var pan: UIPanGestureRecognizer?
+ private var scrollViewUpdater: ScrollViewUpdater?
+
+ private let backgroundView = UIView()
+ private let roundedViewForPresentingView = RoundedView()
+ private let roundedViewForPresentedView = RoundedView()
+
+ private let snapshotViewContainer = UIView()
+ private var snapshotView: UIView?
+
+ private var snapshotViewTopConstraint: NSLayoutConstraint?
+ private var snapshotViewWidthConstraint: NSLayoutConstraint?
+ private var snapshotViewAspectRatioConstraint: NSLayoutConstraint?
+
+ private var presentedViewFrameObserver: NSKeyValueObservation?
+ private var presentedViewTransformObserver: NSKeyValueObservation?
+
+ private var presentAnimation: (() -> ())? = nil
+ private var presentCompletion: ((Bool) -> ())? = nil
+ private var dismissAnimation: (() -> ())? = nil
+ private var dismissCompletion: ((Bool) -> ())? = nil
+
+ // MARK: - Initializers
+
+ convenience init(presentedViewController: UIViewController,
+ presenting presentingViewController: UIViewController?,
+ isSwipeToDismissGestureEnabled: Bool,
+ presentAnimation: (() -> ())? = nil,
+ presentCompletion: ((Bool) ->())? = nil,
+ dismissAnimation: (() -> ())? = nil,
+ dismissCompletion: ((Bool) -> ())? = nil) {
+ self.init(presentedViewController: presentedViewController,
+ presenting: presentingViewController)
+
+ self.isSwipeToDismissGestureEnabled = isSwipeToDismissGestureEnabled
+ self.presentAnimation = presentAnimation
+ self.presentCompletion = presentCompletion
+ self.dismissAnimation = dismissAnimation
+ self.dismissCompletion = dismissCompletion
+
+ NotificationCenter.default.addObserver(self, selector: #selector(updateForStatusBar), name: UIApplication.didChangeStatusBarFrameNotification, object: nil)
+ }
+
+ // MARK: - Public methods
+
+ public func requestPresentedViewSnapshotUpdate() {
+ updateSnapshotView()
+ }
+
+ // MARK: - Sizing
+
+ private var statusBarHeight: CGFloat {
+ return UIApplication.shared.statusBarFrame.height
+ }
+
+ private var scaleForPresentingView: CGFloat {
+ guard let containerView = containerView else {
+ return 0
+ }
+
+ return 1 - (ManualLayout.presentingViewTopInset * 2 / containerView.frame.height)
+ }
+
+ override var frameOfPresentedViewInContainerView: CGRect {
+ guard let containerView = containerView else {
+ return .zero
+ }
+
+ let yOffset = ManualLayout.presentingViewTopInset + Constants.insetForPresentedView
+
+ return CGRect(x: 0,
+ y: yOffset,
+ width: containerView.bounds.width,
+ height: containerView.bounds.height - yOffset)
+ }
+
+ // MARK: - Presentation
+
+ override func presentationTransitionWillBegin() {
+ guard let containerView = containerView, let window = containerView.window else {
+ return
+ }
+
+ /// A CGRect to be used as a proxy for the frame of the presentingView
+ ///
+ /// The actual frame isn't used directly because in the case of the
+ /// double height status bar on non-X iPhones, the containerView has a
+ /// reduced height
+ let initialFrame: CGRect = {
+ if presentingViewController.isPresentedWithDeck {
+ return presentingViewController.view.frame
+ } else {
+ return containerView.bounds
+ }
+ }()
+
+ /// The presented view's rounded view's frame is updated using KVO
+ roundedViewForPresentedView.translatesAutoresizingMaskIntoConstraints = false
+ containerView.addSubview(roundedViewForPresentedView)
+ setupPresentedViewKVO()
+
+ /// The snapshot view initially has the same frame as the presentingView
+ containerView.insertSubview(snapshotViewContainer, belowSubview: presentedViewController.view)
+ snapshotViewContainer.frame = initialFrame
+ updateSnapshotView()
+
+ /// The following transforms are performed on the snapshot view:
+ /// 1. It's frame's origin is reset to 0. This is done because for
+ /// recursive Deck modals, the reference frame will not have its
+ /// origin at `.zero`
+ /// 2. It is translated down by `ManualLayout.presentingViewTopInset`
+ /// points This is the desired inset from the top of the
+ /// containerView
+ /// 3. It is scaled down by `scaleForPresentingView` along both axes,
+ /// such that it's top edge is at the same position. In order to do
+ /// this, we translate it up by half it's height, perform the
+ /// scaling, and then translate it back down by the same amount
+ ///
+ /// On versions of iOS before 11, applying a transform to the parent
+ /// view modifies the frame of subviews immediately to the model value,
+ /// so this transform is applied directly to the snapshot view and not
+ /// the snapshot container view
+ ///
+ /// Note: For some reason, this behaviour only happens in the
+ /// presentation phase; constraints animate as expected on iOS <11 in
+ /// the dismissal 🤷🏽‍♂️
+ let transformForSnapshotView = CGAffineTransform.identity
+ .translatedBy(x: 0, y: -snapshotViewContainer.frame.origin.y)
+ .translatedBy(x: 0, y: ManualLayout.presentingViewTopInset)
+ .translatedBy(x: 0, y: -snapshotViewContainer.frame.height / 2)
+ .scaledBy(x: scaleForPresentingView, y: scaleForPresentingView)
+ .translatedBy(x: 0, y: snapshotViewContainer.frame.height / 2)
+
+ /// For a recursive modal, the `presentingView` already has rounded
+ /// corners so the animation must respect that
+ roundedViewForPresentingView.backgroundColor = UIColor.black.withAlphaComponent(0)
+ roundedViewForPresentingView.cornerRadius = presentingViewController.isPresentedWithDeck ? Constants.cornerRadius : 0
+ containerView.insertSubview(roundedViewForPresentingView, aboveSubview: snapshotViewContainer)
+ roundedViewForPresentingView.frame = initialFrame
+
+ /// The background view is used to cover up the `presentedView`
+ backgroundView.backgroundColor = .black
+ backgroundView.translatesAutoresizingMaskIntoConstraints = false
+ containerView.insertSubview(backgroundView, belowSubview: snapshotViewContainer)
+
+ NSLayoutConstraint.activate([
+ backgroundView.topAnchor.constraint(equalTo: window.topAnchor),
+ backgroundView.leftAnchor.constraint(equalTo: window.leftAnchor),
+ backgroundView.rightAnchor.constraint(equalTo: window.rightAnchor),
+ backgroundView.bottomAnchor.constraint(equalTo: window.bottomAnchor)
+ ])
+
+ /// A snapshot view is used to represent the hierarchy of cards in the
+ /// case of recursive presentation
+ var rootSnapshotView: UIView?
+ var rootSnapshotRoundedView: RoundedView?
+
+ if presentingViewController.isPresentedWithDeck {
+ guard let rootController = presentingViewController.presentingViewController,
+ let snapshotView = rootController.view.snapshotView(afterScreenUpdates: false)
+ else {
+ return
+ }
+
+ containerView.insertSubview(snapshotView, aboveSubview: backgroundView)
+ snapshotView.frame = initialFrame
+ snapshotView.transform = transformForSnapshotView
+ snapshotView.alpha = Constants.alphaForPresentingView
+ rootSnapshotView = snapshotView
+
+ let snapshotRoundedView = RoundedView()
+ snapshotRoundedView.cornerRadius = Constants.cornerRadius
+ containerView.insertSubview(snapshotRoundedView, aboveSubview: snapshotView)
+ snapshotRoundedView.frame = initialFrame
+ snapshotRoundedView.transform = transformForSnapshotView
+ rootSnapshotRoundedView = snapshotRoundedView
+ }
+
+ presentedViewController.transitionCoordinator?.animate(
+ alongsideTransition: { [weak self] context in
+ guard let `self` = self else {
+ return
+ }
+
+ self.presentAnimation?()
+ self.snapshotView?.transform = transformForSnapshotView
+ self.roundedViewForPresentingView.cornerRadius = Constants.cornerRadius
+ self.roundedViewForPresentingView.transform = transformForSnapshotView
+ self.roundedViewForPresentingView.backgroundColor = UIColor.black.withAlphaComponent(1 - Constants.alphaForPresentingView)
+ }, completion: { _ in
+ self.snapshotView?.transform = .identity
+ rootSnapshotView?.removeFromSuperview()
+ rootSnapshotRoundedView?.removeFromSuperview()
+ }
+ )
+ }
+
+ /// Method to ensure the layout is as required at the end of the
+ /// presentation. This is required in case the modal is presented without
+ /// animation.
+ ///
+ /// The various layout related functions performed by this method are:
+ /// - Ensure that the view is in the same state as it would be after
+ /// animated presentation
+ /// - Create and add the `presentingViewSnapshotView` to the view hierarchy
+ /// - Add a black background view to present to complete cover the
+ /// `presentingViewController`'s view
+ /// - Reset the `presentingViewController`'s view's `transform` so that
+ /// further layout updates (such as status bar update) do not break the
+ /// transform
+ ///
+ /// It also sets up the gesture recognizer to handle dismissal of the modal
+ /// view controller by panning downwards
+ override func presentationTransitionDidEnd(_ completed: Bool) {
+ guard let containerView = containerView else {
+ return
+ }
+
+ presentedViewController.view.frame = frameOfPresentedViewInContainerView
+
+ snapshotViewContainer.transform = .identity
+ snapshotViewContainer.translatesAutoresizingMaskIntoConstraints = false
+ snapshotViewContainer.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
+ updateSnapshotViewAspectRatio()
+
+ roundedViewForPresentingView.transform = .identity
+ roundedViewForPresentingView.translatesAutoresizingMaskIntoConstraints = false
+ NSLayoutConstraint.activate([
+ roundedViewForPresentingView.topAnchor.constraint(equalTo: snapshotViewContainer.topAnchor),
+ roundedViewForPresentingView.leftAnchor.constraint(equalTo: snapshotViewContainer.leftAnchor),
+ roundedViewForPresentingView.rightAnchor.constraint(equalTo: snapshotViewContainer.rightAnchor),
+ roundedViewForPresentingView.bottomAnchor.constraint(equalTo: snapshotViewContainer.bottomAnchor)
+ ])
+
+ if isSwipeToDismissGestureEnabled {
+ pan = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
+ pan!.delegate = self
+ pan!.maximumNumberOfTouches = 1
+ pan!.cancelsTouchesInView = false
+ presentedViewController.view.addGestureRecognizer(pan!)
+ }
+
+ presentCompletion?(completed)
+ }
+
+ // MARK: - Layout update methods
+
+ /// This method updates the aspect ratio of the snapshot view
+ ///
+ /// The `snapshotView`'s aspect ratio needs to be updated here because even
+ /// though it is updated with the `snapshotView` in `viewWillTransition:`,
+ /// the transition is janky unless it's updated before, hence it's performed
+ /// here as well, It's also an inexpensive method since constraints are
+ /// modified only when a change is actually needed
+ override func containerViewWillLayoutSubviews() {
+ super.containerViewWillLayoutSubviews()
+
+ guard let containerView = containerView else {
+ return
+ }
+
+ updateSnapshotViewAspectRatio()
+ containerView.bringSubviewToFront(roundedViewForPresentedView)
+
+ if presentedViewController.view.isDescendant(of: containerView) {
+ UIView.animate(withDuration: 0.1) { [weak self] in
+ guard let `self` = self else {
+ return
+ }
+
+ self.presentedViewController.view.frame = self.frameOfPresentedViewInContainerView
+ }
+ }
+ }
+
+ /// Method to handle the modal setup's response to a change in
+ /// orientation, size, etc.
+ ///
+ /// Everything else is handled by AutoLayout or `willLayoutSubviews`; the
+ /// express purpose of this method is to update the snapshot view since that
+ /// is a relatively expensive operation and only makes sense on orientation
+ /// change
+ override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
+ super.viewWillTransition(to: size, with: coordinator)
+
+ coordinator.animate(
+ alongsideTransition: nil,
+ completion: { [weak self] _ in
+ self?.updateSnapshotViewAspectRatio()
+ self?.updateSnapshotView()
+ }
+ )
+ }
+
+ /// Method to handle updating the view when the status bar's height changes
+ ///
+ /// The `containerView`'s frame is always supposed to be the go 20 pixels
+ /// or 1 normal status bar height under the status bar itself, even when the
+ /// status bar is of double height, to retain consistency with the system's
+ /// default behaviour
+ ///
+ /// The containerView is the only thing that received layout updates;
+ /// AutoLayout and the snapshotView method handle the rest. Additionally,
+ /// the mask for the `presentedViewController` is also reset
+ @objc private func updateForStatusBar() {
+ guard let containerView = containerView else {
+ return
+ }
+
+ /// The `presentingViewController.view` often animated "before" the mask
+ /// view that should fully cover it, so it's hidden before altering the
+ /// view hierarchy, and then revealed after the animations are finished
+ presentingViewController.view.alpha = 0
+
+ let fullHeight = containerView.window!.frame.size.height
+
+ let currentHeight = containerView.frame.height
+ let newHeight = fullHeight - ManualLayout.containerViewTopInset
+
+ UIView.animate(
+ withDuration: 0.1,
+ animations: {
+ containerView.frame.origin.y -= newHeight - currentHeight
+ }, completion: { [weak self] _ in
+ self?.presentingViewController.view.alpha = 1
+ containerView.frame = CGRect(x: 0, y: ManualLayout.containerViewTopInset, width: containerView.frame.width, height: newHeight)
+ self?.updateSnapshotView()
+ }
+ )
+ }
+
+ // MARK: - Snapshot view update methods
+
+ /// Method to update the snapshot view showing a representation of the
+ /// `presentingViewController`'s view
+ ///
+ /// The method can only be fired when the snapshot view has been set up, and
+ /// then only when the width of the container is updated
+ ///
+ /// It resets the aspect ratio constraint for the snapshot view first, and
+ /// then generates a new snapshot of the `presentingViewController`'s view,
+ /// and then replaces the existing snapshot with it
+ private func updateSnapshotView() {
+ guard let currentSnapshotView = presentingViewController.view.snapshotView(afterScreenUpdates: true) else {
+ return
+ }
+
+ snapshotView?.removeFromSuperview()
+
+ currentSnapshotView.translatesAutoresizingMaskIntoConstraints = false
+ snapshotViewContainer.addSubview(currentSnapshotView)
+ NSLayoutConstraint.activate([
+ currentSnapshotView.topAnchor.constraint(equalTo: snapshotViewContainer.topAnchor),
+ currentSnapshotView.leftAnchor.constraint(equalTo: snapshotViewContainer.leftAnchor),
+ currentSnapshotView.rightAnchor.constraint(equalTo: snapshotViewContainer.rightAnchor),
+ currentSnapshotView.bottomAnchor.constraint(equalTo: snapshotViewContainer.bottomAnchor)
+ ])
+
+ snapshotView = currentSnapshotView
+ }
+
+ /// Thie method updates the aspect ratio and the height of the snapshot view
+ /// used to represent the presenting view controller.
+ ///
+ /// The aspect ratio is only updated when the width of the container changes
+ /// i.e. when just the status bar moves, nothing happens
+ private func updateSnapshotViewAspectRatio() {
+ guard let containerView = containerView,
+ snapshotViewContainer.translatesAutoresizingMaskIntoConstraints == false
+ else {
+ return
+ }
+
+ snapshotViewTopConstraint?.isActive = false
+ snapshotViewWidthConstraint?.isActive = false
+ snapshotViewAspectRatioConstraint?.isActive = false
+
+ let snapshotReferenceSize = presentingViewController.view.frame.size
+
+ let topInset = ManualLayout.presentingViewTopInset
+
+ let aspectRatio = snapshotReferenceSize.width / snapshotReferenceSize.height
+
+ roundedViewForPresentingView.cornerRadius = Constants.cornerRadius * scaleForPresentingView
+
+ snapshotViewTopConstraint = snapshotViewContainer.topAnchor.constraint(equalTo: containerView.topAnchor, constant: topInset)
+ snapshotViewWidthConstraint = snapshotViewContainer.widthAnchor.constraint(equalTo: containerView.widthAnchor, multiplier: scaleForPresentingView)
+ snapshotViewAspectRatioConstraint = snapshotViewContainer.widthAnchor.constraint(equalTo: snapshotViewContainer.heightAnchor, multiplier: aspectRatio)
+
+ snapshotViewTopConstraint?.isActive = true
+ snapshotViewWidthConstraint?.isActive = true
+ snapshotViewAspectRatioConstraint?.isActive = true
+ }
+
+ // MARK: - Presented view KVO + Rounded view update methods
+
+ private func setupPresentedViewKVO() {
+ presentedViewFrameObserver = presentedViewController.view.observe(\.frame, options: [.initial]) { [weak self] _, _ in
+ self?.presentedViewWasUpdated()
+ }
+
+ presentedViewTransformObserver = presentedViewController.view.observe(\.transform, options: [.initial]) { [weak self] _, _ in
+ self?.presentedViewWasUpdated()
+ }
+ }
+
+ private func invalidatePresentedViewKVO() {
+ presentedViewFrameObserver = nil
+ presentedViewTransformObserver = nil
+ }
+
+ private func presentedViewWasUpdated() {
+ let offset = presentedViewController.view.frame.origin.y
+ roundedViewForPresentedView.frame = CGRect(x: 0, y: offset, width: containerView!.bounds.width, height: Constants.cornerRadius)
+ }
+
+ // MARK: - Dismissal
+
+ /// Method to prepare the view hirarchy for the dismissal animation
+ ///
+ /// The stuff with snapshots and the black background should be invisible to
+ /// the dismissal animation, so this method effectively removes them and
+ /// restores the state of the `presentingViewController`'s view to the
+ /// expected state at the end of the presenting animation
+ override func dismissalTransitionWillBegin() {
+ guard let containerView = containerView else {
+ return
+ }
+
+ let initialFrame: CGRect = {
+ if presentingViewController.isPresentedWithDeck {
+ return presentingViewController.view.frame
+ } else {
+ return containerView.bounds
+ }
+ }()
+
+ let initialTransform = CGAffineTransform.identity
+ .translatedBy(x: 0, y: -initialFrame.origin.y)
+ .translatedBy(x: 0, y: ManualLayout.presentingViewTopInset)
+ .translatedBy(x: 0, y: -initialFrame.height / 2)
+ .scaledBy(x: scaleForPresentingView, y: scaleForPresentingView)
+ .translatedBy(x: 0, y: initialFrame.height / 2)
+
+ roundedViewForPresentingView.translatesAutoresizingMaskIntoConstraints = true
+ roundedViewForPresentingView.frame = initialFrame
+ roundedViewForPresentingView.transform = initialTransform
+
+ snapshotViewTopConstraint?.isActive = false
+ snapshotViewWidthConstraint?.isActive = false
+ snapshotViewAspectRatioConstraint?.isActive = false
+ snapshotViewContainer.translatesAutoresizingMaskIntoConstraints = true
+ snapshotViewContainer.frame = initialFrame
+ snapshotViewContainer.transform = initialTransform
+
+ let finalCornerRadius = presentingViewController.isPresentedWithDeck ? Constants.cornerRadius : 0
+ let finalTransform: CGAffineTransform = .identity
+
+ var rootSnapshotView: UIView?
+ var rootSnapshotRoundedView: RoundedView?
+
+ if presentingViewController.isPresentedWithDeck {
+ guard let rootController = presentingViewController.presentingViewController,
+ let snapshotView = rootController.view.snapshotView(afterScreenUpdates: false)
+ else {
+ return
+ }
+
+ containerView.insertSubview(snapshotView, aboveSubview: backgroundView)
+ snapshotView.frame = initialFrame
+ snapshotView.transform = initialTransform
+ rootSnapshotView = snapshotView
+
+ let snapshotRoundedView = RoundedView()
+ snapshotRoundedView.cornerRadius = Constants.cornerRadius
+ snapshotRoundedView.backgroundColor = UIColor.black.withAlphaComponent(1 - Constants.alphaForPresentingView)
+ containerView.insertSubview(snapshotRoundedView, aboveSubview: snapshotView)
+ snapshotRoundedView.frame = initialFrame
+ snapshotRoundedView.transform = initialTransform
+ rootSnapshotRoundedView = snapshotRoundedView
+ }
+
+ presentedViewController.transitionCoordinator?.animate(
+ alongsideTransition: { [weak self] context in
+ guard let `self` = self else {
+ return
+ }
+
+ self.dismissAnimation?()
+ self.snapshotViewContainer.transform = finalTransform
+ self.roundedViewForPresentingView.transform = finalTransform
+ self.roundedViewForPresentingView.cornerRadius = finalCornerRadius
+ self.roundedViewForPresentingView.backgroundColor = .clear
+ }, completion: { _ in
+ rootSnapshotView?.removeFromSuperview()
+ rootSnapshotRoundedView?.removeFromSuperview()
+ }
+ )
+ }
+
+ /// Method to ensure the layout is as required at the end of the dismissal.
+ /// This is required in case the modal is dismissed without animation.
+ override func dismissalTransitionDidEnd(_ completed: Bool) {
+ guard let containerView = containerView else {
+ return
+ }
+
+ backgroundView.removeFromSuperview()
+ snapshotView?.removeFromSuperview()
+ snapshotViewContainer.removeFromSuperview()
+ roundedViewForPresentingView.removeFromSuperview()
+
+ let offscreenFrame = CGRect(x: 0, y: containerView.bounds.height, width: containerView.bounds.width, height: containerView.bounds.height)
+ presentedViewController.view.frame = offscreenFrame
+ presentedViewController.view.transform = .identity
+
+ invalidatePresentedViewKVO()
+
+ dismissCompletion?(completed)
+ }
+
+ // MARK: - Gesture handling
+
+ private func isSwipeToDismissAllowed() -> Bool {
+ guard let updater = scrollViewUpdater else {
+ return isSwipeToDismissGestureEnabled
+ }
+
+ return updater.isDismissEnabled
+ }
+
+ @objc private func handlePan(gestureRecognizer: UIPanGestureRecognizer) {
+ guard gestureRecognizer.isEqual(pan), isSwipeToDismissGestureEnabled else {
+ return
+ }
+
+ switch gestureRecognizer.state {
+
+ case .began:
+ let detector = ScrollViewDetector(withViewController: presentedViewController)
+ if let scrollView = detector.scrollView {
+ scrollViewUpdater = ScrollViewUpdater(
+ withRootView: presentedViewController.view,
+ scrollView: scrollView)
+ }
+ gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: containerView)
+
+ case .changed:
+ if isSwipeToDismissAllowed() {
+ let translation = gestureRecognizer.translation(in: presentedView)
+ updatePresentedViewForTranslation(inVerticalDirection: translation.y)
+ } else {
+ gestureRecognizer.setTranslation(.zero, in: presentedView)
+ }
+
+ case .ended:
+ UIView.animate(
+ withDuration: 0.25,
+ animations: {
+ self.presentedView?.transform = .identity
+ })
+ scrollViewUpdater = nil
+
+ default: break
+
+ }
+ }
+
+ /// Method to update the modal view for a particular amount of translation
+ /// by panning in the vertical direction.
+ ///
+ /// The translation of the modal view is proportional to the panning
+ /// distance until the `elasticThreshold`, after which it increases at a
+ /// slower rate, given by `elasticFactor`, to indicate that the
+ /// `dismissThreshold` is nearing.
+ ///
+ /// Once the `dismissThreshold` is reached, the modal view controller is
+ /// dismissed.
+ ///
+ /// - parameter translation: The translation of the user's pan gesture in
+ /// the container view in the vertical direction
+ private func updatePresentedViewForTranslation(inVerticalDirection translation: CGFloat) {
+
+ let elasticThreshold: CGFloat = 120
+ let dismissThreshold: CGFloat = 240
+
+ let translationFactor: CGFloat = 1/2
+
+ /// Nothing happens if the pan gesture is performed from bottom
+ /// to top i.e. if the translation is negative
+ if translation >= 0 {
+ let translationForModal: CGFloat = {
+ if translation >= elasticThreshold {
+ let frictionLength = translation - elasticThreshold
+ let frictionTranslation = 30 * atan(frictionLength/120) + frictionLength/10
+ return frictionTranslation + (elasticThreshold * translationFactor)
+ } else {
+ return translation * translationFactor
+ }
+ }()
+
+ presentedView?.transform = CGAffineTransform(translationX: 0, y: translationForModal)
+
+ if translation >= dismissThreshold {
+ presentedViewController.dismiss(animated: true, completion: nil)
+ }
+ }
+ }
+
+ // MARK: - UIGestureRecognizerDelegate methods
+
+ func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
+ guard gestureRecognizer.isEqual(pan) else {
+ return false
+ }
+
+ return true
+ }
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckPresentingAnimationController.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckPresentingAnimationController.swift
new file mode 100755
index 0000000..e898102
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckPresentingAnimationController.swift
@@ -0,0 +1,52 @@
+//
+// DeckPresentingAnimationController.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 15/10/16.
+// Copyright © 2016 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+final class DeckPresentingAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
+
+ // MARK: - Private variables
+
+ private let duration: TimeInterval?
+
+ // MARK: - Initializers
+
+ init(duration: TimeInterval?) {
+ self.duration = duration
+ }
+
+ // MARK: - UIViewControllerAnimatedTransitioning
+
+ func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
+ guard let presentedViewController = transitionContext.viewController(forKey: .to) else {
+ return
+ }
+
+ let containerView = transitionContext.containerView
+ containerView.addSubview(presentedViewController.view)
+ presentedViewController.view.frame = CGRect(x: 0, y: containerView.bounds.height, width: containerView.bounds.width, height: containerView.bounds.height)
+
+ let finalFrameForPresentedView = transitionContext.finalFrame(for: presentedViewController)
+
+ UIView.animate(
+ withDuration: transitionDuration(using: transitionContext),
+ delay: 0,
+ options: .curveEaseOut,
+ animations: {
+ presentedViewController.view.frame = finalFrameForPresentedView
+ }, completion: { finished in
+ transitionContext.completeTransition(finished)
+ })
+ }
+
+ func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
+ return duration ?? Constants.defaultAnimationDuration
+ }
+
+}
+
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckSegue.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckSegue.swift
new file mode 100755
index 0000000..cb5388c
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckSegue.swift
@@ -0,0 +1,27 @@
+//
+// DeckSegue.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 15/10/16.
+// Copyright © 2016 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+/// A segue to implement the Deck transition via Storyboards
+///
+/// To use this, set your segue's class to `DeckSegue`, and its `kind` to
+/// `custom`
+public final class DeckSegue: UIStoryboardSegue {
+
+ var transition: UIViewControllerTransitioningDelegate?
+
+ /// Performs the visual transition for the Deck segue.
+ public override func perform() {
+ transition = DeckTransitioningDelegate()
+ destination.transitioningDelegate = transition
+ destination.modalPresentationStyle = .custom
+ source.present(destination, animated: true, completion: nil)
+ }
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckSnapshotUpdater.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckSnapshotUpdater.swift
new file mode 100755
index 0000000..8e5d555
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckSnapshotUpdater.swift
@@ -0,0 +1,26 @@
+//
+// DeckSnapshotUpdater.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 06/12/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+/// A protocol to communicate to the transition that an update of the snapshot
+/// view is required. This is adopted only by the presentation controller of
+/// any view controller presented using DeckTransition
+public protocol DeckSnapshotUpdater {
+
+ /// For various reasons (performance, the way iOS handles safe area,
+ /// layout issues, etc.) this transition uses a snapshot view of your
+ /// `presentingViewController` and not the live view itself.
+ ///
+ /// In some cases this snapshot might become outdated before the dismissal,
+ /// and for those cases you can request to have the snapshot updated. While
+ /// the transition only shows a small portion of the presenting view, in
+ /// some cases that might become inconsistent enough to demand an update.
+ ///
+ /// This is an expensive process and should only be used if necessary, for
+ /// example if you are updating your entire app's theme.
+ func requestPresentedViewSnapshotUpdate()
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckTransitionViewControllerProtocol.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckTransitionViewControllerProtocol.swift
new file mode 100755
index 0000000..edd0f9e
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckTransitionViewControllerProtocol.swift
@@ -0,0 +1,61 @@
+//
+// DeckTransitionViewControllerProtocol.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 06/12/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+/// A set of methods that vend objects used to customize a DeckTransition
+/// presentation's swipe-to-dismiss behaviour.
+///
+/// The transition has an internal heuristic to determine which `UIScrollView`
+/// should be tracked for the swipe-to-dismiss gesture. However that has some
+/// edge cases, which can we worked around by making your modal view controller
+/// and view controllers presented by or contained within it conform to this
+/// protocol.
+@objc public protocol DeckTransitionViewControllerProtocol: class {
+
+ /// The child view controller which contains the scroll view that should
+ /// be tracked for the swipe-to-dismiss gesture.
+ ///
+ /// The default heuristic for searching the `UIScrollView` to track
+ /// traverses only the first level of subviews of the presented view
+ /// controller. As a result of this, subviews of any child view controller
+ /// are not inspected.
+ ///
+ /// A container view controller presented using DeckTransition can
+ /// implement this variable and return the child view controller which
+ /// contains the scroll view to be tracked.
+ ///
+ /// If this variable is not implemented or is `nil`, then the container view
+ /// controller's own view is searched.
+ ///
+ /// If this variable is implemented and is not `nil`, the container view
+ /// controller's own subviews and the value returned in the
+ /// `scrollViewForDeck` variable are both ignored, and the search continues
+ /// within the child view controller returned here.
+ @objc optional var childViewControllerForDeck: UIViewController? { get }
+
+ /// The scroll view that should be tracked for Deck's swipe-to-dismiss
+ /// gesture.
+ ///
+ /// The default heuristic for searching the `UIScrollView` to track only
+ /// traverses only the first level of subviews of the presented view
+ /// controller, returning the lowermost scroll view found.
+ ///
+ /// This is a similar heuristic to that used in `UINavigationController`
+ /// (which to the best of my knowledge, is even more limited and checks only
+ /// one view, the lowermost subview of the main view), however it can miss
+ /// out on the intended scroll view for more complex view hierarchies.
+ /// For those cases, you can implement this variable and return the
+ /// `UIScrollView` instance which should be tracked.
+ ///
+ /// - Note: The value returned in this variable is ignored if the
+ /// `childViewControllerForDeck` variable is also implemented.
+ @objc optional var scrollViewForDeck: UIScrollView { get }
+
+}
+
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckTransitioningDelegate.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckTransitioningDelegate.swift
new file mode 100755
index 0000000..bb6e3af
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/DeckTransitioningDelegate.swift
@@ -0,0 +1,124 @@
+//
+// DeckTransitioningDelegate.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 15/10/16.
+// Copyright © 2016 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+/// The DeckTransitioningDelegate class vends out the presentation and animation
+/// controllers required to present a view controller with the Deck transition
+/// style
+///
+/// The following snippet described the steps for presenting a given
+/// `ModalViewController` with the `DeckTransitioningDelegate`
+///
+/// ```swift
+/// let modal = ModalViewController()
+/// let transitionDelegate = DeckTransitioningDelegate()
+/// modal.transitioningDelegate = transitionDelegate
+/// modal.modalPresentationStyle = .custom
+/// present(modal, animated: true, completion: nil)
+/// ```
+public final class DeckTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
+
+ // MARK: - Private variables
+
+ private let isSwipeToDismissEnabled: Bool
+ private let presentDuration: TimeInterval?
+ private let presentAnimation: (() -> ())?
+ private let presentCompletion: ((Bool) -> ())?
+ private let dismissDuration: TimeInterval?
+ private let dismissAnimation: (() -> ())?
+ private let dismissCompletion: ((Bool) -> ())?
+
+ // MARK: - Initializers
+
+ /// Returns a transitioning delegate to perform a Deck transition. All
+ /// parameters are optional. Swipe-to-dimiss is enabled by default. Leaving
+ /// the duration parameters empty gives you animations with the default
+ /// durations (0.3s for both)
+ ///
+ /// - Parameters:
+ /// - isSwipeToDismissEnabled: Whether the modal view controller should
+ /// be dismissed with a swipe gesture from top to bottom
+ /// - presentDuration: The duration for the presentation animation
+ /// - presentAnimation: An animation block that will be performed
+ /// alongside the card presentation animation
+ /// - presentCompletion: A block that will be run after the card has been
+ /// presented
+ /// - dismissDuration: The duration for the dismissal animation
+ /// - dismissAnimation: An animation block that will be performed
+ /// alongside the card dismissal animation
+ /// - dismissCompletion: A block that will be run after the card has been
+ /// dismissed
+ @objc public init(isSwipeToDismissEnabled: Bool = true,
+ presentDuration: NSNumber? = nil,
+ presentAnimation: (() -> ())? = nil,
+ presentCompletion: ((Bool) -> ())? = nil,
+ dismissDuration: NSNumber? = nil,
+ dismissAnimation: (() -> ())? = nil,
+ dismissCompletion: ((Bool) -> ())? = nil) {
+ self.isSwipeToDismissEnabled = isSwipeToDismissEnabled
+ self.presentDuration = presentDuration?.doubleValue
+ self.presentAnimation = presentAnimation
+ self.presentCompletion = presentCompletion
+ self.dismissDuration = dismissDuration?.doubleValue
+ self.dismissAnimation = dismissAnimation
+ self.dismissCompletion = dismissCompletion
+ }
+
+ // MARK: - UIViewControllerTransitioningDelegate
+
+ /// Returns an animation controller that animates the modal presentation
+ ///
+ /// This is internal infrastructure handled entirely by UIKit and shouldn't
+ /// be called directly
+ ///
+ /// - Parameters:
+ /// - presented: The modal view controller to be presented onscreen
+ /// - presenting: The view controller that will be presenting the modal
+ /// - source: The view controller whose `present` method is called
+ /// - Returns: An animation controller that animates the modal presentation
+ public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
+ return DeckPresentingAnimationController(duration: presentDuration)
+ }
+
+ /// Returns an animation controller that animates the modal dismissal
+ ///
+ /// This is internal infrastructure handled entirely by UIKit and shouldn't
+ /// be called directly
+ ///
+ /// - Parameter dismissed: The modal view controller which will be dismissed
+ /// - Returns: An animation controller that animates the modal dismisall
+ public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
+ return DeckDismissingAnimationController(duration: dismissDuration)
+ }
+
+ /// Returns a presentation controller that manages the modal presentation
+ ///
+ /// This is internal infrastructure handled entirely by UIKit and shouldn't
+ /// be called directly
+ ///
+ /// - Parameters:
+ /// - presented: The modal view controller
+ /// - presenting: The view controller which presented the modal
+ /// - source: The view controller whose `present` method was called to
+ /// present the modal
+ /// - Returns: A presentation controller that manages the modal presentation
+ public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
+ let presentationController = DeckPresentationController(
+ presentedViewController: presented,
+ presenting: presenting,
+ isSwipeToDismissGestureEnabled: isSwipeToDismissEnabled,
+ presentAnimation: presentAnimation,
+ presentCompletion: presentCompletion,
+ dismissAnimation: dismissAnimation,
+ dismissCompletion: dismissCompletion)
+ presentationController.transitioningDelegate = self
+ return presentationController
+ }
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/CGRect+Corners.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/CGRect+Corners.swift
new file mode 100755
index 0000000..aba6e16
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/CGRect+Corners.swift
@@ -0,0 +1,53 @@
+//
+// CGRect+Corners.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 17/09/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import CoreGraphics
+
+extension CGRect {
+
+ /// Returns the coordinates of a corner of the rectangle
+ ///
+ /// **Important: Values are assumed to be in UIKit's coordinate system i.e.
+ /// with the origin at the top-left**
+ func getCorner(_ corner: Corner) -> CGPoint {
+ switch corner {
+ case .topLeft: return CGPoint(x: minX, y: minY)
+ case .topRight: return CGPoint(x: maxX, y: minY)
+ case .bottomLeft: return CGPoint(x: minX, y: maxY)
+ case .bottomRight: return CGPoint(x: maxX, y: maxY)
+ }
+ }
+
+ /// The coordinates of the top left corner of the rectangle in UIKit's
+ /// coordinate system
+ var topLeft: CGPoint {
+ return getCorner(.topLeft)
+ }
+
+ /// The coordinates of the top right corner of the rectangle in UIKit's
+ /// coordinate system
+ var topRight: CGPoint {
+ return getCorner(.topRight)
+ }
+
+ /// The coordinates of the bottom left corner of the rectangle in UIKit's
+ /// coordinate system
+ var bottomLeft: CGPoint {
+ return getCorner(.bottomLeft)
+ }
+
+ /// The coordinates of the bottom right corner of the rectangle in UIKit's
+ /// coordinate system
+ var bottomRight: CGPoint {
+ return getCorner(.bottomRight)
+ }
+
+}
+
+
+
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/CGRect+InitWithCorner.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/CGRect+InitWithCorner.swift
new file mode 100755
index 0000000..7ce6e09
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/CGRect+InitWithCorner.swift
@@ -0,0 +1,57 @@
+//
+// CGRect+InitWithCorner.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 17/09/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import CoreGraphics
+
+extension CGRect {
+
+ /// Initializes a rectangle using the coordinate of one of its corners and
+ /// its size
+ ///
+ /// **Important: Values are assumed to be in UIKit's coordinate system i.e.
+ /// with the origin at the top-left**
+ ///
+ /// - Parameters:
+ /// - corner: The corner of the rectangle whose location is known
+ /// - cornerPoint: The coordinate of the aforementioned corner
+ /// - size: The size of the rectangle to be created
+ init(withCorner corner: Corner, at cornerLocation: CGPoint, size: CGSize) {
+
+ /// For the left corners, the origin's x-value is the same as that of
+ /// the corner. For right corners, the origin's x-value is calculated by
+ /// shifting the corner left by the width of the rectangle
+ let xOrigin: CGFloat = {
+ switch corner {
+ case .topLeft, .bottomLeft:
+ return cornerLocation.x
+ case .topRight, .bottomRight:
+ return cornerLocation.x - size.width
+ }
+ }()
+
+ /// For the top corners, the origin's y-value is the same as that of
+ /// the corner. For bottom corners, the origin's y-value is calculated
+ /// by shifting the corner up by the height of the rectangle
+ let yOrigin: CGFloat = {
+ switch corner {
+ case .topLeft, .topRight:
+ return cornerLocation.y
+ case .bottomLeft, .bottomRight:
+ return cornerLocation.y - size.height
+ }
+ }()
+
+ let origin = CGPoint(x: xOrigin, y: yOrigin)
+
+ self.init(origin: origin, size: size)
+ }
+
+}
+
+
+
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/UIViewController+DeckTransitionViewControllerProtocol.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/UIViewController+DeckTransitionViewControllerProtocol.swift
new file mode 100755
index 0000000..978b737
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/UIViewController+DeckTransitionViewControllerProtocol.swift
@@ -0,0 +1,29 @@
+//
+// UIViewController+DeckTransitionViewControllerProtocol.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 06/12/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+extension UITabBarController: DeckTransitionViewControllerProtocol {
+
+ /// The view controller representing the selected tab is assumed to contain
+ /// the `UIScrollView` to be tracked
+ public var childViewControllerForDeck: UIViewController? {
+ return self.selectedViewController
+ }
+
+}
+
+extension UINavigationController: DeckTransitionViewControllerProtocol {
+
+ /// The view controller at the top of the navigation stack is assumed to
+ /// contain the `UIScrollView` to be tracked
+ public var childViewControllerForDeck: UIViewController? {
+ return self.topViewController
+ }
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/UIViewController+IsPresentedWithDeck.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/UIViewController+IsPresentedWithDeck.swift
new file mode 100755
index 0000000..232ee5f
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Extensions/UIViewController+IsPresentedWithDeck.swift
@@ -0,0 +1,21 @@
+//
+// UIViewController+IsPresentedWithDeck.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 06/12/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+extension UIViewController {
+
+ /// A Boolean value indicating whether the view controller is presented
+ /// using Deck.
+ var isPresentedWithDeck: Bool {
+ return transitioningDelegate is DeckTransitioningDelegate
+ && modalPresentationStyle == .custom
+ && presentingViewController != nil
+ }
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/ManualLayout.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/ManualLayout.swift
new file mode 100755
index 0000000..fd21d7e
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/ManualLayout.swift
@@ -0,0 +1,59 @@
+//
+// ManualLayout.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 13/09/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+/// A wrapper for a bunch of sizing methods
+final class ManualLayout {
+
+ /// Just a convenience method to access the height of the status bar
+ class var statusBarHeight: CGFloat {
+ return UIApplication.shared.statusBarFrame.height
+ }
+
+ /// The top inset of the containerView within its window based on the status
+ /// bar. This exists entirely because the opaque blue location and green
+ /// in-call status bars on portrait non-X iPhones inset the containerView
+ /// by 20px
+ class var containerViewTopInset: CGFloat {
+ let statusBarHeight = ManualLayout.statusBarHeight
+
+ switch statusBarHeight {
+ case 0: return 0
+ case 20: return 0
+ case 40: return 20
+ case 44: return 0
+ default: return 0
+ }
+ }
+
+ /// The top inset of the presentingView within the containerView.
+ ///
+ /// The values are as follows, for a given value of the status bar:
+ /// - Landscape on iPhone means the status bar is hidden, and since that
+ /// means an extremely wide aspect ratio, the inset is just 8 points
+ /// - On iPads, and with the single-height status bar on portrait, non-X
+ /// iPhones, the status bar is 20px, so the view is also inset by the same
+ /// - With the double-height status bar on portrait, non-X iPhones, the view
+ /// is inset by 20 points since the containerView itself is also inset by
+ /// 20 points
+ /// - On iPhone X in portrait, the inset is the full height of the status
+ /// bar
+ class var presentingViewTopInset: CGFloat {
+ let statusBarHeight = ManualLayout.statusBarHeight
+
+ switch statusBarHeight {
+ case 0: return 8
+ case 20: return 20
+ case 40: return 20
+ case 44: return 44
+ default: return statusBarHeight
+ }
+ }
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/RoundedView/Corner.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/RoundedView/Corner.swift
new file mode 100755
index 0000000..83a2dbe
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/RoundedView/Corner.swift
@@ -0,0 +1,15 @@
+//
+// Corner.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 17/09/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+/// A simple enum used to refer to a `CGRect`'s corner
+enum Corner {
+ case topLeft
+ case topRight
+ case bottomRight
+ case bottomLeft
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/RoundedView/CornerView.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/RoundedView/CornerView.swift
new file mode 100755
index 0000000..1b843d2
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/RoundedView/CornerView.swift
@@ -0,0 +1,181 @@
+//
+// CornerView.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 17/09/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+final class CornerView: UIView {
+
+ // MARK: - Public variables
+
+ var cornerRadius: CGFloat {
+ get { return cornerLayer.radius }
+ set { cornerLayer.radius = newValue }
+ }
+
+ var corner: Corner? {
+ get { return cornerLayer.corner }
+ set { cornerLayer.corner = newValue }
+ }
+
+ // MARK: - Private variables
+
+ private var cornerLayer: CornerLayer {
+ return layer as! CornerLayer
+ }
+
+ // MARK: - Layer override
+
+ override class var layerClass: AnyClass {
+ return CornerLayer.self
+ }
+
+ // MARK: - Initializers
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ setup()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ setup()
+ }
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ setup()
+ }
+
+ private func setup() {
+ cornerLayer.fillColor = UIColor.black.cgColor
+ }
+
+}
+
+private final class CornerLayer: CAShapeLayer {
+
+ // MARK: - Public variables
+
+ override var frame: CGRect {
+ didSet { setNeedsDisplay() }
+ }
+
+ @NSManaged var radius: CGFloat
+
+ var corner: Corner? {
+ didSet { setNeedsDisplay() }
+ }
+
+ // MARK: - Private variables
+
+ private static let radiusKey = "radius"
+
+ // MARK: - Animation overrides
+
+ override static func needsDisplay(forKey key: String) -> Bool {
+ guard key == radiusKey else {
+ return super.needsDisplay(forKey: key)
+ }
+
+ return true
+ }
+
+ override func action(forKey event: String) -> CAAction? {
+ /// As best as I can tell, the only way to get all the properties
+ /// related to the ongoing transition is to just copy them from the
+ /// animation that is created for any random animatable property
+ ///
+ /// https://stackoverflow.com/questions/14192816/create-a-custom-animatable-property
+
+ guard event == CornerLayer.radiusKey,
+ let action = super.action(forKey: "backgroundColor") as? CAAnimation
+ else {
+ return super.action(forKey: event)
+ }
+
+ let animation = CABasicAnimation(keyPath: CornerLayer.radiusKey)
+ animation.fromValue = presentation()?.value(forKey: event) ?? radius
+ animation.duration = action.duration
+ animation.speed = action.speed
+ animation.timeOffset = action.timeOffset
+ animation.repeatCount = action.repeatCount
+ animation.repeatDuration = action.repeatDuration
+ animation.autoreverses = action.autoreverses
+ animation.fillMode = action.fillMode
+ animation.timingFunction = action.timingFunction
+ animation.delegate = action.delegate
+ return animation
+ }
+
+ // MARK: - CALayer methods
+
+ override func display() {
+ self.path = currentPath()
+ }
+
+ // MARK: - Private methods
+
+ private func currentPath() -> CGPath? {
+ guard let corner = corner else {
+ return nil
+ }
+
+ let side = presentation()?.radius ?? radius
+ let size = CGSize(width: side, height: side)
+ let targetRect = CGRect(withCorner: corner, at: bounds.getCorner(corner), size: size)
+
+ /// Each corner's curved path is created by:
+ ///
+ /// 1. Moving to the actual corner point
+ /// 2. Drawing a line along the x-axis towards the center by the same
+ /// amount as the required corner radius
+ /// 3. Drawing a quadrant of the required radius with its center as one
+ /// unit along both x and y axes from the corner towards the center
+ /// 4. Drawing a line back to the corner point
+ let path: UIBezierPath = {
+ switch corner {
+
+ case .topLeft:
+ let tempPath = UIBezierPath()
+ tempPath.move(to: targetRect.topLeft)
+ tempPath.addLine(to: targetRect.topRight)
+ tempPath.addArc(withCenter: targetRect.bottomRight, radius: side, startAngle: .pi * 3/2, endAngle: .pi, clockwise: false)
+ tempPath.addLine(to: targetRect.topLeft)
+ return tempPath
+
+ case .topRight:
+ let tempPath = UIBezierPath()
+ tempPath.move(to: targetRect.topRight)
+ tempPath.addLine(to: targetRect.topLeft)
+ tempPath.addArc(withCenter: targetRect.bottomLeft, radius: side, startAngle: .pi * 3/2, endAngle: 0, clockwise: true)
+ tempPath.addLine(to: targetRect.topRight)
+ return tempPath
+
+ case .bottomLeft:
+ let tempPath = UIBezierPath()
+ tempPath.move(to: targetRect.bottomLeft)
+ tempPath.addLine(to: targetRect.bottomRight)
+ tempPath.addArc(withCenter: targetRect.topRight, radius: side, startAngle: .pi/2, endAngle: .pi, clockwise: true)
+ tempPath.addLine(to: targetRect.bottomLeft)
+ return tempPath
+
+ case .bottomRight:
+ let tempPath = UIBezierPath()
+ tempPath.move(to: targetRect.bottomRight)
+ tempPath.addLine(to: targetRect.bottomLeft)
+ tempPath.addArc(withCenter: targetRect.topLeft, radius: side, startAngle: .pi/2, endAngle: 0, clockwise: false)
+ tempPath.addLine(to: targetRect.bottomRight)
+ return tempPath
+
+ }
+ }()
+
+ return path.cgPath
+ }
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/RoundedView/RoundedView.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/RoundedView/RoundedView.swift
new file mode 100755
index 0000000..e41a5ea
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/RoundedView/RoundedView.swift
@@ -0,0 +1,67 @@
+//
+// RoundedView.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 05/08/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+final class RoundedView: UIView {
+
+ // MARK: - Public variables
+
+ public var cornerRadius = Constants.cornerRadius {
+ didSet {
+ leftCorner.cornerRadius = cornerRadius
+ rightCorner.cornerRadius = cornerRadius
+ }
+ }
+
+ // MARK: - Private variables
+
+ private let leftCorner = CornerView()
+ private let rightCorner = CornerView()
+
+ // MARK: - Initializers
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ setup()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ setup()
+ }
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ setup()
+ }
+
+ private func setup() {
+ leftCorner.corner = .topLeft
+ rightCorner.corner = .topRight
+
+ leftCorner.cornerRadius = cornerRadius
+ rightCorner.cornerRadius = cornerRadius
+
+ leftCorner.translatesAutoresizingMaskIntoConstraints = false
+ rightCorner.translatesAutoresizingMaskIntoConstraints = false
+
+ addSubview(leftCorner)
+ addSubview(rightCorner)
+ }
+
+ // MARK: - UIView methods
+
+ override func layoutSubviews() {
+ super.layoutSubviews()
+
+ leftCorner.frame = bounds
+ rightCorner.frame = bounds
+ }
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/ScrollViewDetector.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/ScrollViewDetector.swift
new file mode 100755
index 0000000..7981804
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/ScrollViewDetector.swift
@@ -0,0 +1,71 @@
+//
+// ScrollViewDetector.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 06/12/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+/// An encapsulation for the logic used to parse a view controller hierarchy
+/// and detect the scroll view to be tracked for the swipe-to-dismiss gesture
+final class ScrollViewDetector {
+
+ // MARK: - Public variables
+
+ weak var scrollView: UIScrollView?
+
+ // MARK: - Initializers
+
+ init(withViewController viewController: UIViewController) {
+ let topViewController = getVisibleViewController(fromViewController: viewController)
+ self.scrollView = getScrollView(fromViewController: topViewController)
+ }
+
+ // MARK: - Private methods
+
+ /// Returns the view controller whose `view` should be searched for the
+ /// `UIScrollView` to track.
+ ///
+ /// - Parameter viewController: The view controller from which the search
+ /// should begin.
+ /// - Returns: The view controller whose `view` must be searched.
+ private func getVisibleViewController(fromViewController viewController: UIViewController) -> UIViewController {
+ guard let deckViewController = viewController as? DeckTransitionViewControllerProtocol,
+ let childViewController = deckViewController.childViewControllerForDeck as? UIViewController
+ else {
+ return viewController
+ }
+
+ return getVisibleViewController(fromViewController: childViewController)
+ }
+
+ /// Returns the `UIScrollView` which should be tracked.
+ ///
+ /// - Parameter viewController: The view controller whose view hierarchy
+ /// must be searched.
+ /// - Returns: The scrollView specified in the
+ /// `DeckTransitionViewControllerProtocol` implementation if one exists,
+ /// failing which the lowermost `UIScrollView` in the view's top level
+ /// subviews, or nil if one isn't found.
+ private func getScrollView(fromViewController viewController: UIViewController) -> UIScrollView? {
+ if let deckViewController = viewController as? DeckTransitionViewControllerProtocol,
+ let scrollView = deckViewController.scrollViewForDeck {
+ return scrollView
+ }
+
+ if let scrollView = viewController.view as? UIScrollView {
+ return scrollView
+ }
+
+ for subview in viewController.view.subviews {
+ if let scrollView = subview as? UIScrollView {
+ return scrollView
+ }
+ }
+
+ return nil
+ }
+
+}
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/ScrollViewUpdater.swift b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/ScrollViewUpdater.swift
new file mode 100755
index 0000000..af7f42e
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/ScrollViewUpdater.swift
@@ -0,0 +1,97 @@
+//
+// ScrollViewUpdater.swift
+// DeckTransition
+//
+// Created by Harshil Shah on 06/12/17.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+import UIKit
+
+/// This class is responsible for animating and managing state for a given
+/// `UIScrollView`.
+///
+/// It has two linked jobs:
+/// 1. Animate the card effect bounce when the scroll view is scrolled beyond
+/// the top.
+/// 2. Signal whether the scroll view can currently be dismissed, used by the
+/// `DeckPresentationController` to help with handling the swipe-to-dismiss
+/// pan gesture.
+final class ScrollViewUpdater {
+
+ // MARK: - Public variables
+
+ var isDismissEnabled = false
+
+ // MARK: - Private variables
+
+ private weak var rootView: UIView?
+ private weak var scrollView: UIScrollView?
+ private var observation: NSKeyValueObservation?
+
+ // MARK: - Initializers
+
+ init(withRootView rootView: UIView, scrollView: UIScrollView) {
+ self.rootView = rootView
+ self.scrollView = scrollView
+ self.observation = scrollView.observe(\.contentOffset, options: [.initial], changeHandler: { [weak self] _, _ in
+ self?.scrollViewDidScroll()
+ })
+ }
+
+ deinit {
+ observation = nil
+ }
+
+ // MARK: - Private methods
+
+ private func scrollViewDidScroll() {
+ guard let rootView = rootView, let scrollView = scrollView else {
+ return
+ }
+
+ /// Since iOS 11, the "top" position of a `UIScrollView` is not when
+ /// its `contentOffset.y` is 0, but when `contentOffset.y` added to it's
+ /// `safeAreaInsets.top` is 0, so that is adjusted for here.
+ let offset: CGFloat = {
+ if #available(iOS 11, *) {
+ return scrollView.contentOffset.y + scrollView.contentInset.top + scrollView.safeAreaInsets.top
+ } else {
+ return scrollView.contentOffset.y + scrollView.contentInset.top
+ }
+ }()
+
+ /// If the `scrollView` is not at the top, then do nothing.
+ /// Additionally, dismissal is not allowed.
+ ///
+ /// If the `scrollView` is at the top or beyond, but is decelerating,
+ /// this means that it reached to the top as the result of momentum from
+ /// a swipe. In these cases, in order to retain the "card" effect, we
+ /// move the `rootView` and the `scrollView`'s contents to make it
+ /// appear as if the entire presented card is shifting down.
+ ///
+ /// Lastly, if the `scrollView` is at the top or beyond and isn't
+ /// decelerating, then that means that the user is panning from top to
+ /// bottom and has no more space to scroll within the `scrollView`.
+ /// The pan gesture which controls the dismissal is allowed to take over
+ /// now, and the scrollView's natural bounce is stopped.
+
+ if offset > 0 {
+ scrollView.bounces = true
+ isDismissEnabled = false
+ } else {
+ if scrollView.isDecelerating {
+ rootView.transform = CGAffineTransform(translationX: 0, y: -offset)
+ scrollView.subviews.forEach {
+ $0.transform = CGAffineTransform(translationX: 0, y: offset)
+ }
+ } else {
+ scrollView.bounces = false
+ isDismissEnabled = true
+ }
+ }
+ }
+
+}
+
+
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Supporting Files/DeckTransition.h b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Supporting Files/DeckTransition.h
new file mode 100755
index 0000000..52bd41a
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Supporting Files/DeckTransition.h
@@ -0,0 +1,17 @@
+//
+// DeckTransition.h
+// DeckTransition
+//
+// Created by Harshil Shah on 4/8/2017.
+// Copyright © 2017 Harshil Shah. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+//! Project version number for DeckTransition.
+FOUNDATION_EXPORT double DeckTransitionVersionNumber;
+
+//! Project version string for DeckTransition.
+FOUNDATION_EXPORT const unsigned char DeckTransitionVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import <DeckTransition/PublicHeader.h>
diff --git a/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Supporting Files/Info.plist b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Supporting Files/Info.plist
new file mode 100755
index 0000000..e6b8c56
--- /dev/null
+++ b/node_modules/react-native-navigation/lib/ios/DeckTransition/Source/Supporting Files/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleShortVersionString</key>
+ <string>2.1</string>
+ <key>CFBundleVersion</key>
+ <string>$(CURRENT_PROJECT_VERSION)</string>
+ <key>NSPrincipalClass</key>
+ <string></string>
+</dict>
+</plist>
diff --git a/node_modules/react-native-navigation/lib/ios/RNNCommandsHandler.m b/node_modules/react-native-navigation/lib/ios/RNNCommandsHandler.m
index 8a1b3ee..8ee239f 100644
--- a/node_modules/react-native-navigation/lib/ios/RNNCommandsHandler.m
+++ b/node_modules/react-native-navigation/lib/ios/RNNCommandsHandler.m
@@ -9,6 +9,15 @@
#import "UIViewController+RNNOptions.h"
#import "React/RCTI18nUtil.h"
+// See: https://github.com/CocoaPods/CocoaPods/issues/7594
+#if __has_include("DeckTransition-Swift.h")
+ #define HAS_DECK_TRANSITION
+ #import "DeckTransition-Swift.h"
+#elif __has_include("DeckTransition/DeckTransition-Swift.h")
+ #define HAS_DECK_TRANSITION
+ #import <DeckTransition/DeckTransition-Swift.h>
+#endif
+
static NSString* const setRoot = @"setRoot";
static NSString* const setStackRoot = @"setStackRoot";
static NSString* const push = @"push";
@@ -253,7 +262,33 @@ - (void)showModal:(NSDictionary*)layout completion:(RNNTransitionWithComponentId
UIViewController<RNNParentProtocol> *newVc = [_controllerFactory createLayout:layout];
[newVc renderTreeAndWait:[newVc.resolveOptions.animations.showModal.waitForRender getWithDefaultValue:NO] perform:^{
- [_modalManager showModal:newVc animated:[newVc.getCurrentChild.resolveOptions.animations.showModal.enable getWithDefaultValue:YES] hasCustomAnimation:newVc.getCurrentChild.resolveOptions.animations.showModal.hasCustomAnimation completion:^(NSString *componentId) {
+ id transitioningDelegate;
+
+ if ([newVc.getCurrentChild.resolveOptions.animations.showModal.enableDeck getWithDefaultValue:NO]) {
+#ifdef HAS_DECK_TRANSITION
+ transitioningDelegate = [[DeckTransitioningDelegate alloc]
+ initWithIsSwipeToDismissEnabled:[newVc.getCurrentChild.resolveOptions.animations.showModal.enableDeckSwipeToDismiss getWithDefaultValue:YES]
+ presentDuration:[NSNumber numberWithDouble:[newVc.getCurrentChild.resolveOptions.animations.showModal.deckPresentDuration getWithDefaultValue:0.3]]
+ presentAnimation:nil
+ presentCompletion:nil
+ dismissDuration:[NSNumber numberWithDouble:[newVc.getCurrentChild.resolveOptions.animations.showModal.deckDismissDuration getWithDefaultValue:0.3]]
+ dismissAnimation:nil
+ dismissCompletion:nil
+ ];
+#else
+ // TODO: Write installation instructions
+ [[NSException exceptionWithName:@"DeckTransitionNotIncludedError"
+ reason:@"DeckTransition has not been included! Refer to installation instructions on how to add it."
+ userInfo:nil]
+ raise];
+#endif
+ }
+
+ [_modalManager showModal:newVc
+ animated:[newVc.getCurrentChild.resolveOptions.animations.showModal.enable getWithDefaultValue:YES]
+ hasCustomAnimation:newVc.getCurrentChild.resolveOptions.animations.showModal.hasCustomAnimation
+ transitioningDelegate:transitioningDelegate
+ completion:^(NSString *componentId) {
[_eventEmitter sendOnNavigationCommandCompletion:showModal params:@{@"layout": layout}];
completion(componentId);
}];
diff --git a/node_modules/react-native-navigation/lib/ios/RNNModalManager.h b/node_modules/react-native-navigation/lib/ios/RNNModalManager.h
index 04f9245..a7b9c1e 100644
--- a/node_modules/react-native-navigation/lib/ios/RNNModalManager.h
+++ b/node_modules/react-native-navigation/lib/ios/RNNModalManager.h
@@ -14,7 +14,7 @@
@property (nonatomic, weak) id<RNNModalManagerDelegate> delegate;
- (void)showModal:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNTransitionWithComponentIdCompletionBlock)completion;
-- (void)showModal:(UIViewController *)viewController animated:(BOOL)animated hasCustomAnimation:(BOOL)hasCustomAnimation completion:(RNNTransitionWithComponentIdCompletionBlock)completion;
+- (void)showModal:(UIViewController *)viewController animated:(BOOL)animated hasCustomAnimation:(BOOL)hasCustomAnimation transitioningDelegate:(id)transitioningDelegate completion:(RNNTransitionWithComponentIdCompletionBlock)completion;
- (void)dismissModal:(UIViewController *)viewController completion:(RNNTransitionCompletionBlock)completion;
- (void)dismissAllModalsAnimated:(BOOL)animated;
diff --git a/node_modules/react-native-navigation/lib/ios/RNNModalManager.m b/node_modules/react-native-navigation/lib/ios/RNNModalManager.m
index 947cdb3..85a8485 100644
--- a/node_modules/react-native-navigation/lib/ios/RNNModalManager.m
+++ b/node_modules/react-native-navigation/lib/ios/RNNModalManager.m
@@ -16,10 +16,10 @@ -(instancetype)init {
}
-(void)showModal:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
- [self showModal:viewController animated:animated hasCustomAnimation:NO completion:completion];
+ [self showModal:viewController animated:animated hasCustomAnimation:NO transitioningDelegate:nil completion:completion];
}
--(void)showModal:(UIViewController *)viewController animated:(BOOL)animated hasCustomAnimation:(BOOL)hasCustomAnimation completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
+-(void)showModal:(UIViewController *)viewController animated:(BOOL)animated hasCustomAnimation:(BOOL)hasCustomAnimation transitioningDelegate:(id)transitioningDelegate completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
if (!viewController) {
@throw [NSException exceptionWithName:@"ShowUnknownModal" reason:@"showModal called with nil viewController" userInfo:nil];
}
@@ -27,7 +27,10 @@ -(void)showModal:(UIViewController *)viewController animated:(BOOL)animated hasC
UIViewController* topVC = [self topPresentedVC];
topVC.definesPresentationContext = YES;
- if (hasCustomAnimation) {
+ if (transitioningDelegate) {
+ viewController.transitioningDelegate = transitioningDelegate;
+ viewController.modalPresentationStyle = UIModalPresentationCustom;
+ } else if (hasCustomAnimation) {
viewController.transitioningDelegate = (UIViewController<UIViewControllerTransitioningDelegate>*)topVC;
}
diff --git a/node_modules/react-native-navigation/lib/ios/RNNScreenTransition.h b/node_modules/react-native-navigation/lib/ios/RNNScreenTransition.h
index 0e2b408..75dc408 100644
--- a/node_modules/react-native-navigation/lib/ios/RNNScreenTransition.h
+++ b/node_modules/react-native-navigation/lib/ios/RNNScreenTransition.h
@@ -10,6 +10,11 @@
@property (nonatomic, strong) Bool* enable;
@property (nonatomic, strong) Bool* waitForRender;
+@property (nonatomic, strong) Bool* enableDeck;
+@property (nonatomic, strong) Bool* enableDeckSwipeToDismiss;
+@property (nonatomic, strong) Double* deckPresentDuration;
+@property (nonatomic, strong) Double* deckDismissDuration;
+
- (BOOL)hasCustomAnimation;
@end
diff --git a/node_modules/react-native-navigation/lib/ios/RNNScreenTransition.m b/node_modules/react-native-navigation/lib/ios/RNNScreenTransition.m
index 8bdff88..aeb183b 100644
--- a/node_modules/react-native-navigation/lib/ios/RNNScreenTransition.m
+++ b/node_modules/react-native-navigation/lib/ios/RNNScreenTransition.m
@@ -11,6 +11,11 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
self.enable = [BoolParser parse:dict key:@"enabled"];
self.waitForRender = [BoolParser parse:dict key:@"waitForRender"];
+ self.enableDeck = [BoolParser parse:dict key:@"enableDeck"];
+ self.enableDeckSwipeToDismiss = [BoolParser parse:dict key:@"enableDeckSwipeToDismiss"];
+ self.deckPresentDuration = [DoubleParser parse:dict key:@"deckPresentDuration"];
+ self.deckDismissDuration = [DoubleParser parse:dict key:@"deckDismissDuration"];
+
return self;
}
diff --git a/node_modules/react-native-navigation/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj b/node_modules/react-native-navigation/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj
index a7c1acb..e768c5e 100644
--- a/node_modules/react-native-navigation/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj
+++ b/node_modules/react-native-navigation/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj
@@ -221,8 +221,8 @@
50BE951320B5A787004F5DF5 /* RNNStatusBarOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50BE951120B5A787004F5DF5 /* RNNStatusBarOptions.h */; };
50C4A496206BDDBB00DB292E /* RNNSubtitleOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C4A494206BDDBB00DB292E /* RNNSubtitleOptions.h */; };
50C4A497206BDDBB00DB292E /* RNNSubtitleOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50C4A495206BDDBB00DB292E /* RNNSubtitleOptions.m */; };
- 50C5FD8220D7D6D600F1EA8A /* ReactNativeNavigation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7BA500731E2544B9001B9E1B /* ReactNativeNavigation.h */; };
- 50C5FD8320D7D6DD00F1EA8A /* RNNBridgeManagerDelegate.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 502CB43920CBCA140019B2FE /* RNNBridgeManagerDelegate.h */; };
+ 50C5FD8220D7D6D600F1EA8A /* ReactNativeNavigation.h in Copy Files */ = {isa = PBXBuildFile; fileRef = 7BA500731E2544B9001B9E1B /* ReactNativeNavigation.h */; };
+ 50C5FD8320D7D6DD00F1EA8A /* RNNBridgeManagerDelegate.h in Copy Files */ = {isa = PBXBuildFile; fileRef = 502CB43920CBCA140019B2FE /* RNNBridgeManagerDelegate.h */; };
50CB3B691FDE911400AA153B /* RNNSideMenuOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB3B671FDE911400AA153B /* RNNSideMenuOptions.h */; };
50CB3B6A1FDE911400AA153B /* RNNSideMenuOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50CB3B681FDE911400AA153B /* RNNSideMenuOptions.m */; };
50CE8503217C6C9B00084EBF /* RNNSideMenuPresenterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 50CE8502217C6C9B00084EBF /* RNNSideMenuPresenterTest.m */; };
@@ -239,6 +239,7 @@
50F5DFC21F407A8C001A00BC /* RNNTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50F5DFC01F407A8C001A00BC /* RNNTabBarController.m */; };
50F5DFC51F407AA0001A00BC /* RNNNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F5DFC31F407AA0001A00BC /* RNNNavigationController.h */; };
50F5DFC61F407AA0001A00BC /* RNNNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50F5DFC41F407AA0001A00BC /* RNNNavigationController.m */; };
+ 5893FF2D221F07670004659C /* DeckTransition.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5859B236221EDB7100CD7755 /* DeckTransition.framework */; };
651E1F8A21FD624600DFEA19 /* UISplitViewController+RNNOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 651E1F8921FD624600DFEA19 /* UISplitViewController+RNNOptions.m */; };
651E1F8D21FD642100DFEA19 /* RNNSplitViewControllerPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 651E1F8C21FD642100DFEA19 /* RNNSplitViewControllerPresenter.m */; };
7365071121E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 7365070F21E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.h */; };
@@ -312,6 +313,20 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
+ 5859B235221EDB7100CD7755 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 5859B227221EDB5700CD7755 /* DeckTransition.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D93F1C981EAEDB6E009A7474;
+ remoteInfo = DeckTransition;
+ };
+ 5859B237221EDB7100CD7755 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 5859B227221EDB5700CD7755 /* DeckTransition.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D93F1CA11EAEDB6E009A7474;
+ remoteInfo = DeckTransitionTests;
+ };
7B49FEC11E95090800DEB3EA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D8AFADB51BEE6F3F00A4592D /* Project object */;
@@ -322,15 +337,16 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
- D8AFADBB1BEE6F3F00A4592D /* CopyFiles */ = {
+ D8AFADBB1BEE6F3F00A4592D /* Copy Files */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
- 50C5FD8320D7D6DD00F1EA8A /* RNNBridgeManagerDelegate.h in CopyFiles */,
- 50C5FD8220D7D6D600F1EA8A /* ReactNativeNavigation.h in CopyFiles */,
+ 50C5FD8320D7D6DD00F1EA8A /* RNNBridgeManagerDelegate.h in Copy Files */,
+ 50C5FD8220D7D6D600F1EA8A /* ReactNativeNavigation.h in Copy Files */,
);
+ name = "Copy Files";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
@@ -570,6 +586,7 @@
50F5DFC01F407A8C001A00BC /* RNNTabBarController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTabBarController.m; sourceTree = "<group>"; };
50F5DFC31F407AA0001A00BC /* RNNNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNNavigationController.h; sourceTree = "<group>"; };
50F5DFC41F407AA0001A00BC /* RNNNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationController.m; sourceTree = "<group>"; };
+ 5859B227221EDB5700CD7755 /* DeckTransition.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = DeckTransition.xcodeproj; path = DeckTransition/DeckTransition.xcodeproj; sourceTree = "<group>"; };
651E1F8821FD611600DFEA19 /* UISplitViewController+RNNOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UISplitViewController+RNNOptions.h"; sourceTree = "<group>"; };
651E1F8921FD624600DFEA19 /* UISplitViewController+RNNOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UISplitViewController+RNNOptions.m"; sourceTree = "<group>"; };
651E1F8B21FD63F400DFEA19 /* RNNSplitViewControllerPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSplitViewControllerPresenter.h; sourceTree = "<group>"; };
@@ -684,6 +701,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5893FF2D221F07670004659C /* DeckTransition.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -990,6 +1008,23 @@
name = Managers;
sourceTree = "<group>";
};
+ 5859B230221EDB6B00CD7755 /* Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 5859B227221EDB5700CD7755 /* DeckTransition.xcodeproj */,
+ );
+ name = Libraries;
+ sourceTree = "<group>";
+ };
+ 5859B231221EDB7100CD7755 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 5859B236221EDB7100CD7755 /* DeckTransition.framework */,
+ 5859B238221EDB7100CD7755 /* DeckTransitionTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
7B1E4C4B1E2D173700C3A525 /* Controllers */ = {
isa = PBXGroup;
children = (
@@ -1121,6 +1156,7 @@
263905881E4C6F440023D7D3 /* RNNSideMenu */,
507F43F11FF4FCD800D9425B /* HMSegmentControl */,
7B49FEBC1E95090800DEB3EA /* ReactNativeNavigationTests */,
+ 5859B230221EDB6B00CD7755 /* Libraries */,
D8AFADBE1BEE6F3F00A4592D /* Products */,
7B49FED01E950A7A00DEB3EA /* Frameworks */,
E8367B791F77BA1F00675C05 /* Recovered References */,
@@ -1350,7 +1386,7 @@
buildPhases = (
D8AFADB91BEE6F3F00A4592D /* Sources */,
D8AFADBA1BEE6F3F00A4592D /* Frameworks */,
- D8AFADBB1BEE6F3F00A4592D /* CopyFiles */,
+ D8AFADBB1BEE6F3F00A4592D /* Copy Files */,
7B1126A21E2D2B5500F9B03B /* Headers */,
);
buildRules = (
@@ -1391,6 +1427,12 @@
mainGroup = D8AFADB41BEE6F3F00A4592D;
productRefGroup = D8AFADBE1BEE6F3F00A4592D /* Products */;
projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = 5859B231221EDB7100CD7755 /* Products */;
+ ProjectRef = 5859B227221EDB5700CD7755 /* DeckTransition.xcodeproj */;
+ },
+ );
projectRoot = "";
targets = (
D8AFADBC1BEE6F3F00A4592D /* ReactNativeNavigation */,
@@ -1399,6 +1441,23 @@
};
/* End PBXProject section */
+/* Begin PBXReferenceProxy section */
+ 5859B236221EDB7100CD7755 /* DeckTransition.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = DeckTransition.framework;
+ remoteRef = 5859B235221EDB7100CD7755 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 5859B238221EDB7100CD7755 /* DeckTransitionTests.xctest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = DeckTransitionTests.xctest;
+ remoteRef = 5859B237221EDB7100CD7755 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
/* Begin PBXResourcesBuildPhase section */
7B49FEB91E95090800DEB3EA /* Resources */ = {
isa = PBXResourcesBuildPhase;
@@ -1744,6 +1803,7 @@
D8AFADC71BEE6F3F00A4592D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_STRICT_PROTOTYPES = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
@@ -1761,6 +1821,7 @@
D8AFADC81BEE6F3F00A4592D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_STRICT_PROTOTYPES = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
diff --git a/node_modules/react-native-navigation/lib/src/interfaces/Options.ts b/node_modules/react-native-navigation/lib/src/interfaces/Options.ts
index e1d35f9..2993b44 100644
--- a/node_modules/react-native-navigation/lib/src/interfaces/Options.ts
+++ b/node_modules/react-native-navigation/lib/src/interfaces/Options.ts
@@ -763,6 +763,24 @@ export interface OptionsAnimationSeparate {
* Configure animations for the content (Screen)
*/
content?: OptionsAnimationPropertiesId;
+ /**
+ * Disable/Enable deck transition [Default: false]
+ *
+ * Warning: IOS only
+ */
+ enableDeck?: boolean,
+ /**
+ * Disable/Enable swipe to dismiss interaction [Default: true]
+ */
+ enableDeckSwipeToDismiss?: boolean,
+ /**
+ * Duration of the appear animation in seconds [Default: 0.3]
+ */
+ deckPresentDuration?: boolean,
+ /**
+ * Duration of the dismiss animation in seconds [Default: 0.3]
+ */
+ deckDismissDuration?: boolean,
}
export interface OptionsAnimations {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment