Instantly share code, notes, and snippets.
Last active
March 13, 2019 15:37
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save Jyrno42/de6cbc417d3f829a49b20db3775409cc to your computer and use it in GitHub Desktop.
Patch file for https://github.com/wix/react-native-navigation/pull/4774 - use via patch-package - https://www.npmjs.com/package/patch-package
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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