Skip to content

Commit

Permalink
[RN][macos] Fix disable scrolling for multiline text input
Browse files Browse the repository at this point in the history
Summary:
# Context

RN iOS supports disabling scrolling via `scrollEnabled` prop for multiline text inputs.
https://reactnative.dev/docs/0.68/textinput#scrollenabled-ios

This does [not work](microsoft#925) on MacOS

Since MacOS does not use `UITextView` which inherits from `UIScrollView`, the view manager property was set but not actually passed down to the underlying scroll view.

`RCTMultilineTextInputView` creates a `RCTUIScrollView` which is where we need to disable scrolling.
https://www.internalfb.com/code/archon_react_native_macos/[fde4113acd89fb13ee11636c48b59eac49c21bae]/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m?lines=31

`RCTUIScrollView` inherits from `NSScrollView` which does not have a `scrollEnabled` property, but there is an api we can use to disable scrolling when the property is set.

https://developer.apple.com/documentation/appkit/nsscrollview/1403494-scrollwheel

# Usage

NOTE: Only works with `multiline={true}`

```
<TextInput multiline={true} scrollEnabled={false} ... />
```

# Change

* Only expose the `scrollEnabled` property on `RCTMultilineTextInputView`.
  * `RCTSinglelineTextInputView` does not have scrolling so this property is unused.
* `RCTMultilineTextInputView` delegates the `scrollEnabled` to it's underlying `_scrollView`
* `RCTUIScrollView` defaults initial `scrollEnabled` to `YES`
* `RCTUIScrollView` disables scrolling when the `scrollEnabled` is `NO`
  • Loading branch information
Shawn Dempsey authored and shwanton committed Jul 12, 2022
1 parent 1498fe5 commit 0146e2b
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ NS_ASSUME_NONNULL_BEGIN

@interface RCTMultilineTextInputView : RCTBaseTextInputView

#if TARGET_OS_OSX
@property (nonatomic, assign) BOOL scrollEnabled;
#endif

@end

NS_ASSUME_NONNULL_END
10 changes: 10 additions & 0 deletions Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.m
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ - (void)setReactBorderInsets:(UIEdgeInsets)reactBorderInsets
_scrollView.frame = UIEdgeInsetsInsetRect(self.bounds, reactBorderInsets);
[self setNeedsLayout];
}

- (void)setScrollEnabled:(BOOL)scrollEnabled
{
_scrollView.scrollEnabled = scrollEnabled;
}

- (BOOL)scrollEnabled
{
return _scrollView.scrollEnabled;
}
#endif // ]TODO(macOS GH#774)

#pragma mark - UIScrollViewDelegate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ - (RCTUIView *)view // TODO(macOS ISS#3536887)

RCT_REMAP_NOT_OSX_VIEW_PROPERTY(dataDetectorTypes, backedTextInputView.dataDetectorTypes, UIDataDetectorTypes) // TODO(macOS GH#774)
RCT_REMAP_OSX_VIEW_PROPERTY(dataDetectorTypes, backedTextInputView.enabledTextCheckingTypes, NSTextCheckingTypes) // TODO(macOS GH#774)
RCT_EXPORT_VIEW_PROPERTY(scrollEnabled, BOOL)

@end
1 change: 0 additions & 1 deletion Libraries/Text/TextInput/RCTBaseTextInputViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ @implementation RCTBaseTextInputViewManager
RCT_REMAP_OSX_VIEW_PROPERTY(spellCheck, backedTextInputView.automaticSpellingCorrectionEnabled, BOOL) // TODO(macOS GH#774)
RCT_REMAP_NOT_OSX_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL) // TODO(macOS GH#774)
RCT_REMAP_NOT_OSX_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode) // TODO(macOS GH#774)
RCT_REMAP_VIEW_PROPERTY(scrollEnabled, backedTextInputView.scrollEnabled, BOOL)
RCT_REMAP_NOT_OSX_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) // TODO(macOS GH#774)
RCT_EXPORT_VIEW_PROPERTY(autoFocus, BOOL)
RCT_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL)
Expand Down
1 change: 1 addition & 0 deletions React/Base/RCTUIKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ CGPathRef UIBezierPathCreateCGPathRef(UIBezierPath *path);
@property (nonatomic, assign) CGFloat zoomScale;
@property (nonatomic, assign) BOOL alwaysBounceHorizontal;
@property (nonatomic, assign) BOOL alwaysBounceVertical;
@property (nonatomic, assign) BOOL scrollEnabled;

@end

Expand Down
19 changes: 19 additions & 0 deletions React/Base/macOS/RCTUIKit.m
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,15 @@ - (void)setBackgroundColor:(NSColor *)backgroundColor

@implementation RCTUIScrollView // TODO(macOS ISS#3536887)

- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.scrollEnabled = YES;
}

return self;
}

// UIScrollView properties missing from NSScrollView
- (CGPoint)contentOffset
{
Expand Down Expand Up @@ -522,6 +531,16 @@ - (void)setAlwaysBounceVertical:(BOOL)alwaysBounceVertical
self.verticalScrollElasticity = alwaysBounceVertical ? NSScrollElasticityAllowed : NSScrollElasticityNone;
}

- (void)scrollWheel:(NSEvent *)theEvent
{
if (self.scrollEnabled == NO) {
[[self nextResponder] scrollWheel:theEvent];
return;
}

[super scrollWheel:theEvent];
}

@end

BOOL RCTUIViewSetClipsToBounds(RCTPlatformView *view)
Expand Down

0 comments on commit 0146e2b

Please sign in to comment.