Skip to content

Commit bce2ae6

Browse files
authored
Fix drawing over bottom tabs (#17)
1 parent 1aaa551 commit bce2ae6

File tree

7 files changed

+66
-63
lines changed

7 files changed

+66
-63
lines changed

android/src/main/java/com/multiplemodals/RNTModalView.kt

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ import android.view.ViewStructure
99
import android.view.accessibility.AccessibilityEvent
1010
import com.facebook.react.bridge.LifecycleEventListener
1111
import com.facebook.react.bridge.UiThreadUtil
12-
import com.facebook.react.uimanager.PixelUtil
1312
import com.facebook.react.uimanager.ThemedReactContext
1413
import com.facebook.react.uimanager.UIManagerHelper
1514
import com.facebook.react.uimanager.events.EventDispatcher
1615
import com.multiplemodals.events.PressBackEvent
1716
import com.multiplemodals.library.ModalDialog
18-
import com.multiplemodals.library.ModalHostHelper
1917
import com.multiplemodals.library.ModalView
2018
import com.multiplemodals.library.OnSizeComputedListener
2119

@@ -30,25 +28,9 @@ class RNTModalView(context: Context): ViewGroup(context), LifecycleEventListener
3028
modalView.onSizeComputedListener = value
3129
}
3230

33-
internal fun requestViewSizeComputation() {
34-
val modalSize = ModalHostHelper.getModalHostSize(context)
35-
36-
onSizeComputedListener?.onSizeComputed(
37-
id,
38-
PixelUtil.toDIPFromPixel(modalSize.x.toFloat()),
39-
PixelUtil.toDIPFromPixel(modalSize.y.toFloat()),
40-
)
41-
}
42-
4331
private val surfaceId: Int get() = UIManagerHelper.getSurfaceId(this)
4432

45-
override fun setId(id: Int) {
46-
super.setId(id)
47-
// Id is passed to control shadow node size
48-
modalView.id = id
49-
}
50-
51-
private val reactContext: ThemedReactContext get() = context as ThemedReactContext
33+
internal val reactContext: ThemedReactContext get() = context as ThemedReactContext
5234
private val eventDispatcher: EventDispatcher
5335
private val modalDialog: ModalDialog
5436
private val modalView: ModalView

android/src/main/java/com/multiplemodals/library/ModalView.kt

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ import android.view.View
66
import com.facebook.react.config.ReactFeatureFlags
77
import com.facebook.react.uimanager.JSPointerDispatcher
88
import com.facebook.react.uimanager.JSTouchDispatcher
9-
import com.facebook.react.uimanager.PixelUtil
109
import com.facebook.react.uimanager.RootView
1110
import com.facebook.react.uimanager.ThemedReactContext
1211
import com.facebook.react.uimanager.events.EventDispatcher
1312
import com.facebook.react.views.view.ReactViewGroup
1413

1514
fun interface OnSizeComputedListener {
16-
fun onSizeComputed(id: Int, widthDip: Float, heightDip: Float)
15+
fun onSizeComputed(widthPx: Int, heightPx: Int)
1716
}
1817

1918
@SuppressLint("ViewConstructor")
@@ -26,11 +25,7 @@ class ModalView(reactContext: ThemedReactContext,
2625

2726
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
2827
super.onSizeChanged(w, h, oldw, oldh)
29-
onSizeComputedListener?.onSizeComputed(
30-
id,
31-
PixelUtil.toDIPFromPixel(w.toFloat()),
32-
PixelUtil.toDIPFromPixel(h.toFloat())
33-
)
28+
onSizeComputedListener?.onSizeComputed(w, h)
3429
}
3530

3631
init {

android/src/newarch/RNTModalViewManagerSpec.kt

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ package com.multiplemodals
33
import android.view.ViewGroup
44
import com.facebook.react.bridge.WritableMap
55
import com.facebook.react.bridge.WritableNativeMap
6+
import com.facebook.react.uimanager.PixelUtil
67
import com.facebook.react.uimanager.ReactStylesDiffMap
78
import com.facebook.react.uimanager.StateWrapper
89
import com.facebook.react.uimanager.ViewGroupManager
910
import com.facebook.react.uimanager.ViewManagerDelegate
1011
import com.facebook.react.viewmanagers.RNTModalViewManagerDelegate
1112
import com.facebook.react.viewmanagers.RNTModalViewManagerInterface
13+
import com.multiplemodals.library.ModalHostHelper
1214
import com.multiplemodals.library.OnSizeComputedListener
1315
import kotlin.math.roundToInt
1416

@@ -19,6 +21,15 @@ abstract class RNTModalViewManagerSpec<T : ViewGroup> : ViewGroupManager<T>(), R
1921
return mDelegate
2022
}
2123

24+
private fun computeViewSize(view: RNTModalView) {
25+
val modalSize = ModalHostHelper.getModalHostSize(view.context)
26+
27+
view.onSizeComputedListener?.onSizeComputed(
28+
modalSize.x,
29+
modalSize.y,
30+
)
31+
}
32+
2233
override fun updateState(
2334
view: T,
2435
props: ReactStylesDiffMap,
@@ -34,20 +45,20 @@ abstract class RNTModalViewManagerSpec<T : ViewGroup> : ViewGroupManager<T>(), R
3445
}
3546
}
3647

37-
view.onSizeComputedListener = OnSizeComputedListener { _, widthDip, heightDip ->
38-
val nextWidthDip = widthDip.roundToInt()
39-
val nextHeightDip = heightDip.roundToInt()
48+
view.onSizeComputedListener = OnSizeComputedListener { widthPx, heightPx ->
49+
val nextWidthDip = PixelUtil.toDIPFromPixel(widthPx.toFloat()).roundToInt()
50+
val nextHeightDip = PixelUtil.toDIPFromPixel(heightPx.toFloat()).roundToInt()
4051

4152
// Comparing props prevents infinite update cycle
4253
if (currentWidthDip != nextWidthDip || currentHeightDip != nextHeightDip) {
4354
val newStateData: WritableMap = WritableNativeMap()
44-
newStateData.putDouble("screenWidth", widthDip.toDouble())
45-
newStateData.putDouble("screenHeight", heightDip.toDouble())
55+
newStateData.putDouble("screenWidth", nextWidthDip.toDouble())
56+
newStateData.putDouble("screenHeight", nextHeightDip.toDouble())
4657
stateWrapper.updateState(newStateData)
4758
}
4859
}
4960

50-
view.requestViewSizeComputation()
61+
computeViewSize(view)
5162
view.show()
5263
}
5364

android/src/oldarch/RNTModalViewManagerSpec.kt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,27 @@ package com.multiplemodals
22

33
import android.view.ViewGroup
44
import com.facebook.react.bridge.GuardedRunnable
5-
import com.facebook.react.uimanager.ThemedReactContext
65
import com.facebook.react.uimanager.UIManagerModule
76
import com.facebook.react.uimanager.ViewGroupManager
87
import com.multiplemodals.library.OnSizeComputedListener
9-
import kotlin.math.roundToInt
108

119
abstract class RNTModalViewManagerSpec<T : ViewGroup> : ViewGroupManager<T>() {
1210
override fun onAfterUpdateTransaction(view: T) {
13-
if (view is RNTModalView) {
14-
super.onAfterUpdateTransaction(view)
11+
super.onAfterUpdateTransaction(view)
1512

13+
if (view is RNTModalView) {
1614
// set by RNTModalShadowView for paper arch
1715
view.isShadowViewSizeSet = true
1816

19-
view.onSizeComputedListener = OnSizeComputedListener { id, widthDip, heightDip ->
20-
val reactContext = view.context as ThemedReactContext
17+
view.onSizeComputedListener = OnSizeComputedListener { widthPx, heightPx ->
18+
val reactContext = view.reactContext
2119

2220
reactContext.runOnNativeModulesQueueThread(
2321
object : GuardedRunnable(reactContext) {
2422
override fun runGuarded() {
2523
reactContext.reactApplicationContext
2624
.getNativeModule(UIManagerModule::class.java)
27-
?.updateNodeSize(id, widthDip.roundToInt(), heightDip.roundToInt())
25+
?.updateNodeSize(view.id, widthPx, heightPx)
2826
}
2927
})
3028
}

ios/Fabric/RNTModalViewComponentView.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ NS_ASSUME_NONNULL_BEGIN
1212

1313
@interface RNTModalViewComponentView : RCTViewComponentView
1414

15-
@property(nonatomic, strong) RCTSurfaceTouchHandler *touchHandler;
16-
@property(nonatomic, strong) RNTModalViewController *modalViewController;
15+
@property(nullable, strong) RCTSurfaceTouchHandler *touchHandler;
16+
@property(nullable, strong) RNTModalViewController *modalViewController;
1717
@property(nonatomic, assign) BOOL isMounted;
1818

1919
- (void)setupIfNeeded;

ios/Fabric/RNTModalViewComponentView.mm

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ @implementation RNTModalViewComponentView {
2525
RNTModalViewShadowNode::ConcreteState::Shared _state;
2626
}
2727

28+
+ (BOOL)shouldBeRecycled
29+
{
30+
return NO;
31+
}
32+
2833
- (instancetype)initWithFrame:(CGRect)frame
2934
{
3035
self = [super initWithFrame:CGRectZero];
@@ -43,13 +48,15 @@ - (instancetype)initWithFrame:(CGRect)frame
4348

4449
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
4550
{
46-
[self insertReactSubview:childComponentView atIndex:index];
51+
[self.touchHandler attachToView:childComponentView];
52+
[self.modalViewController addReactSubview:childComponentView];
4753
[self setupIfNeeded];
4854
}
4955

5056
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
5157
{
52-
[self removeReactSubview:childComponentView];
58+
[self.touchHandler detachFromView:childComponentView];
59+
[childComponentView removeFromSuperview];
5360
[self unmount];
5461
}
5562

@@ -63,30 +70,14 @@ - (void)didMoveToSuperview {
6370

6471
- (void)layoutSubviews {
6572
[super layoutSubviews];
73+
6674
[self setupIfNeeded];
6775
}
6876

6977
- (void)addSubview:(UIView *)view {
7078
[super addSubview:view];
7179
}
7280

73-
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex {
74-
[super insertReactSubview:subview atIndex:atIndex];
75-
dispatch_async(dispatch_get_main_queue(), ^{
76-
[self.touchHandler attachToView:subview];
77-
[self.modalViewController addReactSubview:subview];
78-
});
79-
}
80-
81-
- (void)removeReactSubview:(UIView *)subview
82-
{
83-
[super removeReactSubview:subview];
84-
dispatch_async(dispatch_get_main_queue(), ^{
85-
[self.touchHandler detachFromView:subview];
86-
[subview removeFromSuperview];
87-
});
88-
}
89-
9081
- (void)setupIfNeeded {
9182
if (self.isMounted) {
9283
[self update];
@@ -95,8 +86,20 @@ - (void)setupIfNeeded {
9586
}
9687
}
9788

89+
- (UIViewController *)getRootController {
90+
UIWindow *keyWindow = [UIApplication sharedApplication].windows.firstObject;
91+
for (UIWindow *window in [UIApplication sharedApplication].windows) {
92+
if (window.isKeyWindow) {
93+
keyWindow = window;
94+
break;
95+
}
96+
}
97+
UIViewController *topController = keyWindow.rootViewController;
98+
return topController;
99+
}
100+
98101
- (void)mount {
99-
UIViewController *rvc = [self reactViewController];
102+
UIViewController *rvc = [self getRootController];
100103
if (!rvc) {
101104
NSLog(@"reactViewController not found");
102105
return;
@@ -111,7 +114,9 @@ - (void)mount {
111114

112115
- (void)unmount {
113116
[self.modalViewController dismiss];
114-
self.isMounted = NO;
117+
_isMounted = NO;
118+
_modalViewController = NULL;
119+
_touchHandler = NULL;
115120
}
116121

117122
- (void)update {

ios/RNTModalView.m

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,20 @@ - (void)setupIfNeeded {
5353
}
5454
}
5555

56+
- (UIViewController *)getRootViewController {
57+
UIWindow *keyWindow = [UIApplication sharedApplication].windows.firstObject;
58+
for (UIWindow *window in [UIApplication sharedApplication].windows) {
59+
if (window.isKeyWindow) {
60+
keyWindow = window;
61+
break;
62+
}
63+
}
64+
UIViewController *topController = keyWindow.rootViewController;
65+
return topController;
66+
}
67+
5668
- (void)mount {
57-
UIViewController *rvc = [self reactViewController];
69+
UIViewController *rvc = [self getRootViewController];
5870
if (!rvc) {
5971
NSLog(@"reactViewController not found");
6072
return;

0 commit comments

Comments
 (0)