Summary: It saves 8 bytes per shadowView instance, and it is more logical because it does nothing by default.
Reviewed By: javache
Differential Revision: D5997804
fbshipit-source-id: c985a11aeea881e95911469e10c8c27429a2718a
Summary:
This is required for D5874536, wherein I'll be introducing direction-aware props for borders.
When a view's border changes due to a direction update, only the frames of its children update. Therefore, only the children `UIView`s get a chance to be re-rendered. This is incorrect because the view that's had its borders changed also needs to re-render. So, I keep a track of the layout direction in a property on all shadow views. Then, when I update that prop within `applyLayoutNode`, I push shadow views into the `viewsWithNewFrames` set.
Reviewed By: mmmulani
Differential Revision: D5944488
fbshipit-source-id: 3f23e9973f3555612920703cdb6cec38e6360d2d
Summary: Because `RCTUIManager` is already overcomplicated and that stuff deserves separate file and header.
Reviewed By: javache
Differential Revision: D5856653
fbshipit-source-id: 7001bb8ba611976bf3b82d6a25f5619810a35b34
Summary:
This issue has been open for a really long time, but I'm pretty sure this is the line that needed to change:
https://github.com/facebook/react-native/issues/1831
What was happening here is that `CGRectIsEmpty` returns true when either height or width is zero. With the current logic, one of those would always be zero when the parent was rendered off screen. This ensures that there the intersection be of CGSizeZero for the view to actually be clipped.
That being said, there seems to be something more complex going on here that I'm not understanding? I would think that you'd simply want to check if the child view's frame is within the bounds of the parent at all. If it was, then don't clip it. If I'm in the wrong, could someone explain this a bit more? If so, I'll fix this issue.
Using this [repository](https://github.com/jcharlet/react_native_listview_bug), this one line change fixes the issue and still clips cells as they are scrolled off screen.
Closes https://github.com/facebook/react-native/pull/15669
Differential Revision: D5815056
Pulled By: shergin
fbshipit-source-id: 32382e4954139e4d5af67d786422fd87173b1a1a
Summary: As per the comment, <Modal> uses entering/leaving the view hierarchy as a cue to show/hide the modal. By re-adding it, we are causing a bunch of confusion.
Reviewed By: shergin
Differential Revision: D5893607
fbshipit-source-id: ecd05799751a9bba843998ae93f24fe35edca8b4
Summary:
<SafeAreaView> renders nested content and automatically applies paddings reflect the portion of the view
that is not covered by navigation bars, tab bars, toolbars, and other ancestor views.
Moreover, and most importantly, Safe Area's paddings feflect physical limitation of the screen,
such as rounded corners or camera notches (aka sensor housing area on iPhone X).
Reviewed By: mmmulani
Differential Revision: D5886411
fbshipit-source-id: 7ecc7aa34de8f5527c4e59b0fb4efba3aaea28c8
Summary:
In some cases we need a way to specify some environmental data to shadow view
to improve layout (or do something similar), so `localData` serves these needs.
For example, any stateful embedded native views may benefit from this.
Have in mind that this data is not supposed to interfere with the state of
the shadow view.
Reviewed By: mmmulani
Differential Revision: D5884711
fbshipit-source-id: f0bf66e4608894ec4479b8aca262afcfba6b9f4b
Summary: Adds an onDismiss so that navigation events can be chained to the dismissing of a modal.
Reviewed By: sahrens
Differential Revision: D5852953
fbshipit-source-id: a86e36fdd5b0b206c2dd9fa248e2a88da22efa31
Summary:
fix the regression I mentioned in https://github.com/facebook/react-native/pull/15162#issuecomment-319696706
as no one is working on this, I take the step, although I know nothing about Objective C
I find the key point is that the keys in `NSDictionary` are not ordered as presented, it's a hash table, so no grantee on keys order, so I create a new array to do that, then it will check `ultralight` before `light` and `semibold` before `bold`
Closes https://github.com/facebook/react-native/pull/15825
Differential Revision: D5782142
Pulled By: shergin
fbshipit-source-id: 5346b0cb263e535c0b445e7a2912c452573248a5
Summary:
Shame on me.
Naming can be hard. We have to use positive logic to avoid this kind of bugs. :(
In the bright future we also have to rename `isYogaLeafNode` to something with positive logic, like `canHaveYogaChildNodes`.
But before we can do this, we have to have solid plan how to unify it with Android.
Reviewed By: mmmulani
Differential Revision: D5780917
fbshipit-source-id: 1ddaaea06f5618b91528cc87f1433a55b5fae4ac
Summary:
Content offset was broken because on initial render contentSize is {0,0} so any positive offset is lost. Also inset top/bottom and left/right were inversed �, this led to bad initial scrolling offset when using contentInset. This fixes it by making sure contentSize is actually measured (not {0,0}. I guess it's possible that the content is ACTUALLY {0,0} but in that case I don't think it really matters).
**Test plan**
Tested that a scrollview has proper scroll position when specifying contentOffset. Also tested that it works well with contentInset.
```js
<ScrollView contentOffset={{y: 100}}>
<View style={{height: 1000}} />
</ScrollView>
```
Closes https://github.com/facebook/react-native/pull/15670
Differential Revision: D5771221
Pulled By: shergin
fbshipit-source-id: 455ed8fd5a4ad1ec61780b573d1a8ef1d77dd124
Summary:
We have to have a way to track ownership of shadow view.
Previous solution with traversing the hierarchy to figure out the root view does not actually work in some cases when the view is temporary detached from hierarchy.
This is also how it work on Andorid.
Reviewed By: mmmulani
Differential Revision: D5686112
fbshipit-source-id: a23a10e8c29c7572ac69403289db136c9d5176a9
Summary:
- [x] Explain the **motivation** for making this change.
- [x] Provide a **test plan** demonstrating that the code is solid.
- [x] Match the **code formatting** of the rest of the codebase.
- [x] Target the `master` branch, NOT a "stable" branch.
There is a problem where setting a bigger fontSize in PickerItem style
clips the top and bottom of the text.
This solves that problem by computing the row height using the font
size.
Create a PickerIOS component and set a larger font size (e.g. 50). The row height will grow accordingly.
Example with `fontSize=50`: [Screenshot](http://i.imgur.com/YwK5fOc.png)
Closes https://github.com/facebook/react-native/pull/13513
Differential Revision: D5692124
Pulled By: shergin
fbshipit-source-id: 4629403e37ad68cdbc0b17b48ba924a77e133078
Summary:
> The property contentInset can change the maximum and minimum values of the content offset to allow scrolling outside of the scrollable area. Its type is UIEdgeInsets, which consists of 4 numbers: {top, left, bottom, right}. When you introduce an inset, you change the range of the content offset. For example, setting the content inset to have a value of 10 for its top value allows the content offset’s y value to reach -10. This introduces padding around the scrollable area.
( https://www.objc.io/issues/3-views/scroll-view/ )
See also: https://github.com/facebook/react-native/pull/15395
Reviewed By: mmmulani
Differential Revision: D5607192
fbshipit-source-id: 1acd6a84e2bcfefc6e82861cfbdfe6247d0e4264
Summary:
**Motivation**
On Apple TV, pressing the menu button destroys the native view that backs the `Modal` component, causing an app using this component to get into a broken state. This fix implements `onRequestClose` for tvOS to have the same behavior as it does for the Android back button.
**Test plan**
Manually tested this with the `ModalExample` in the `RNTester` app. See also the test code in issue #15313.
Closes https://github.com/facebook/react-native/pull/15341
Differential Revision: D5651035
Pulled By: shergin
fbshipit-source-id: 54bf66887bbe85940567e63e90b437ac4a8daf9a
Summary:
**Motivation**
Fix flickering in TabBarIOS on Apple TV... issue #15081
After this change, on Apple TV, TabBarIOS item selections will be controlled purely from the native side after initial render with the `selected` prop. This is necessary because the `UITabBar` implementation in tvOS moves the selection before calling `shouldSelectViewController:`; this issue does not occur on iOS.
**Test plan**
Existing CI should still pass. Issue is resolved when testing the example code in #15081 .
Closes https://github.com/facebook/react-native/pull/15220
Differential Revision: D5601671
Pulled By: javache
fbshipit-source-id: c18e7d3482d6c07d534ff40a443a6f642d4267bb
Summary:
It is not itemPositoning it is itemPositioning
I have test it on iOS and tvOS
Closes https://github.com/facebook/react-native/pull/15426
Differential Revision: D5591807
Pulled By: javache
fbshipit-source-id: 0ad0bc32012c63f93f6b1528cae46c6dcba56706
Summary:
When false, ScrollView disables use of pinch gestures to zoom in and out. This allows ScrollView's pinch gesture responder to be disabled to only allow zooming programmatically. The default value is ~false~ true.
**Test Plan**
Tested that pinch gesture responder is disabled when pinchEnabled=false.
/cc nicklockwood sahrens
🍺
Closes https://github.com/facebook/react-native/pull/10037
Differential Revision: D5491953
Pulled By: shergin
fbshipit-source-id: eae16f92ec616e415b4ddacfccb84c697582daf9
Summary:
Hey!
So, I was interested to contibure, and started from todo
Thank
Closes https://github.com/facebook/react-native/pull/14823
Differential Revision: D5546610
Pulled By: javache
fbshipit-source-id: 58e1b67786cbafa20399ac12dde9fcc3920abe94
Summary:
In iOS11, Apple added a new layout feature called "Safe Areas" (this blog post talks a bit about it: https://www.bignerdranch.com/blog/wwdc-2017-large-titles-and-safe-area-layout-guides/).
UIScrollView is one component that is affected by this change in Apple's API. When the `contentInsetAdjustmentBehavior` is set to `automatic`, for example, it will adjust the insets (and override any manually set insets) automatically based on whether or not there's a UINavigationBar, a UITabBar, a visible status bar, etc on the screen. Frustratingly, Apple decided to default to `Automatic` for this behavior, which will cause any apps that set contentInset/contentContainerStyle padding to have their values offset by, at the very least, the size of the status bar, when they compile their app for iOS 11. Here's more information about this behavior: https://developer.apple.com/documentation/uikit/uiscrollview/2902261-contentinsetadjustmentbehavior?language=objc
Mostly, this is a really straightforward change -- it simply adds a new iOS-only prop to ScrollView that allows setting `contentInsetAdjustmentBehavior`. But I did decide to default the behavior to `never`, so that it mimics the behavior we've seen in iOS < 11. I think it's good to keep something as crucial as scrollview content insets non-magical, and also keep it behaving similarly between platforms.
Closes https://github.com/facebook/react-native/pull/15023
Reviewed By: javache
Differential Revision: D5517552
Pulled By: hramos
fbshipit-source-id: c9ce4bf331b3d243228268d826fdd4dcee99981d
Summary:
Adds a queue to postMessage so that messages sent close together are not lost.
Setting location="a";location="b" results in only "b" reaching shouldStartLoadWithRequest. Making the second update asynchronous with setTimeout does not fix the issue unless a delay is added.
With this update, postMessage queues "b" until it gets a "message:received" event that confirms "a" has already been processed.
The included test sends two messages from a webview and checks that both are received. It fails against the preexisting code with the first message being dropped.
Closes https://github.com/facebook/react-native/pull/11304
Differential Revision: D5481385
Pulled By: hramos
fbshipit-source-id: 9b6af195eeff8f20c820e2fcdac997c90763e840
Summary:
In iOS11, Apple added a new layout feature called "Safe Areas" (this blog post talks a bit about it: https://www.bignerdranch.com/blog/wwdc-2017-large-titles-and-safe-area-layout-guides/).
UIScrollView is one component that is affected by this change in Apple's API. When the `contentInsetAdjustmentBehavior` is set to `automatic`, for example, it will adjust the insets (and override any manually set insets) automatically based on whether or not there's a UINavigationBar, a UITabBar, a visible status bar, etc on the screen. Frustratingly, Apple decided to default to `Automatic` for this behavior, which will cause any apps that set contentInset/contentContainerStyle padding to have their values offset by, at the very least, the size of the status bar, when they compile their app for iOS 11. Here's more information about this behavior: https://developer.apple.com/documentation/uikit/uiscrollview/2902261-contentinsetadjustmentbehavior?language=objc
Mostly, this is a really straightforward change -- it simply adds a new iOS-only prop to ScrollView that allows setting `contentInsetAdjustmentBehavior`. But I did decide to default the behavior to `never`, so that it mimics the behavior we've seen in iOS < 11. I think it's good to keep something as crucial as scrollview content insets non-magical, and also keep it behaving similarly between platforms.
Closes https://github.com/facebook/react-native/pull/15023
Differential Revision: D5441491
Pulled By: shergin
fbshipit-source-id: 7b56ea290f7f6eca5f1d996ff8488f40b866c2e6
Summary:
**Issue:**
Some fonts are defined with weights that don't match with the UIFontWeight constants.
**Example:**
UIFontWeightTraits for Roboto font
Light: -0.230
Thin: -0.365
Currently, the UIFontWeightTrait is always used if it != 0.0, and given the UIFontWeight constants for Light and Thin:
UIFontWeightThin -0.6
UIFontWeightLight -0.4
A style font weight of "300" or "200" will both resolve to Roboto-Thin as its weight -0.365 is closer to -0.4 (UIFontWeightLight) and -0.6 (UIFontWeightThin) than -0.230 (Roboto-Light).
**Proposed fix:**
When resolving `getWeightOfFont` try to match the name of weight to the name of the font first, and guess the font with UIFontWeightTrait as the fall back.
**Test Plan:**
Attempt to display Roboto at weights "200" and "300" and Roboto-Thin and Roboto-Light should be displayed correctly.
Current:
![simulator screen shot jul 7 2017 11 44 42 am](https://user-images.githubusercontent.com/889895/28506859-31b274e8-6fe3-11e7-8f92-f41ff2183356.png)
Fixed:
![simulator screen shot jul 7 2017 11 42 25 am](https://user-images.githubusercontent.com/889895/28506861-365ea3f4-6fe3-11e7-992c-9f426785037f.png)
Closes https://github.com/facebook/react-native/pull/15162
Differential Revision: D5479817
Pulled By: javache
fbshipit-source-id: a9f93d8ce69a96fb685cb09393d1db42486cc0c2
Summary:
<!--
Thank you for sending the PR!
If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!
Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.
Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/15156
Differential Revision: D5479265
Pulled By: shergin
fbshipit-source-id: a2dfa3a4357e126838a17dac4797d1d845cd56ae
Summary:
* Now `setFrame:` is called by autoresizing masks, so it is safe.
* Nobody calls `setBounds:`, so it is also safe.
Reviewed By: javache
Differential Revision: D5414441
fbshipit-source-id: 6fc51c7598c4817301db51f627aa1e9840642fec
Summary:
Previous `contentOffset` can be invalid for a new layout and overscroll the ScrollView, so the diff fixes that.
Also documented here: https://github.com/facebook/react-native/issues/13566
Reviewed By: mmmulani
Differential Revision: D5414442
fbshipit-source-id: 7de1b4a4571108a37d1795e80f165bca5aba5fef
Summary:
Surprisingly enough, even if semantically the code remains identical, layouting via autoresizing masks applies changes to subviews a bit earlier than iOS calls `layoutSubviews`.
This allows us to avoid situations where we already explicitly set calculated by Yoga frames and want to scroll to some subview, but actual layout have not done yet and internal views has wrong frames.
Reviewed By: javache
Differential Revision: D5414440
fbshipit-source-id: d4152c9c68dc17f6827832dcb45e5ba86fb82831
Summary:
This PR fixes#15006 by removing all UI API calls from RCTScrollEvent.
`-[RCTScrollEvent arguments]` can now be called from a background thread.
The Main Thread Checker of Xcode 9 will not any longer produce runtime issues when calling this method.
1. create a React Native (version: this PR) project with a scroll view
2. open it in Xcode 9
3. launch it
4. scroll the scroll view
5. observe the runtime issues in Xcode. There should not contain "UI API called from background thread"-issues.
I verified my changes on this branch: https://github.com/HeEAaD/Demo-ReactNative-UI-not-on-main-thread/tree/fix
<!--
Thank you for sending the PR!
If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!
Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.
Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/15008
Differential Revision: D5424734
Pulled By: shergin
fbshipit-source-id: 56beec2d7603ea6782d55622567509f3758a4517
Summary:
It's very important in complex UIs to be able to apply alpha channel-based masks to arbitrary content. Common use cases include adding gradient masks at the top or bottom of scroll views, creating masked text effects, feathering images, and generally just masking views while still allowing transparency of those views.
The original motivation for creating this component stemmed from work on `react-navigation`. As I tried to mimic behavior in the native iOS header, I needed to be able to achieve the effect pictured here (this is a screenshot from a native iOS application):
![iOS native navbar animation](https://slack-imgs.com/?c=1&url=https%3A%2F%2Fd3vv6lp55qjaqc.cloudfront.net%2Fitems%2F0N3g1Q3H423P3m1c1z3E%2FScreen%2520Shot%25202017-07-06%2520at%252011.57.29%2520AM.png)
In this image, there are two masks:
- A mask on the back button chevron
- A gradient mask on the right button
In addition, the underlying view in the navigation bar is intended to be a UIBlurView. Thus, alpha masking is the only way to achieve this effect.
Behind the scenes, the `maskView` property on `UIView` is used. This is a shortcut to setting the mask on the CALayer directly.
This gives us the ability to mask any view with any other view. While building this component (and testing in the context of an Expo app), I was able to use a `GLView` (a view that renders an OpenGL context) to mask a `Video` component!
I chose to implement this only on iOS right now, as the Android implementation is a) significantly more complicated and b) will most likely not be as performant (especially when trying to mask more complex views).
Review the `<MaskedViewIOS>` section in the RNTester app, observe that views are masked appropriately.
![example](https://d3vv6lp55qjaqc.cloudfront.net/items/250X092v2k3f212f3O16/Screen%20Recording%202017-07-07%20at%2012.18%20PM.gif?X-CloudApp-Visitor-Id=abb33b3e3769bbe2f7b26d13dc5d1442&v=5f9e2d4c)
Closes https://github.com/facebook/react-native/pull/14898
Differential Revision: D5398721
Pulled By: javache
fbshipit-source-id: 343af874e2d664541aca1fefe922cf7d82aea701
Summary:
**Motivation**
This is a re-worked version of #14260, by shergin's suggestion.
For iOS, if you want to inherit from a native ViewManagers, your custom ViewManager will not automatically export the parents' props. So the only way to do this today, is to basically copy/paste the parent ViewManager-file, and add your own custom logic.
With this PR, this is made more extensible by exporting the `baseModuleName` (i.e. the iOS `superclass` of the ViewManager), and then using that value to re-establish the inheritance relationship in `requireNativeComponent`.
**Test plan**
I've run this with a test project, and it works fine there. But needs more testing.
Opened this PR as [per shergin's suggestion](https://github.com/facebook/react-native/pull/10946#issuecomment-311860545) though, so we can discuss approach.
**Discussion**
* Android already supports inheritance, so this change should be compatible with that. But, not every prop available on `UIManager.RCTView.NativeProps` is actually exported by every ViewManager. So should `UIManager.RCTView.NativeProps` still be merged with `viewConfig.NativeProps`, even if the individual ViewManager does not export/use them to begin with?
* Does this break other platforms? [UWP](https://github.com/Microsoft/react-native-windows)?
Closes https://github.com/facebook/react-native/pull/14775
Differential Revision: D5392953
Pulled By: shergin
fbshipit-source-id: 5212da616acfba50cc285e2997d183cf8b2cd09f
Summary:
Thanks for submitting a pull request! Please provide enough information so that others can review your pull request:
> **Unless you are a React Native release maintainer and cherry-picking an *existing* commit into a current release, ensure your pull request is targeting the `master` React Native branch.**
Explain the **motivation** for making this change. What existing problem does the pull request solve?
The problem occurs when a ScrollView's content height is smaller than the ScrollView height. If the method `scrollToEnd` is called on the ScrollView, it will pull the content down until the bottom of the content is aligned with the bottom of the Scrollview container.
This fix will ensure the proper functionality: That the furthest the ScrollView can scroll down is to where the top of the content container is at the origin (i.e., the ScrollView scroll number cannot be less than 0).
Prefer **small pull requests**. These are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.
**Test plan (required)**
Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI.
Make sure tests pass on both Travis and Circle CI.
I tested on a scenario where the ScrollView is almost the full size of the screen, and the content of the ScrollView has a height of much less. In this situation, the `scrollToEnd` method was executed and the content stayed in the same position. This is the intended behavior. If the content of the ScrollView is smaller than the height of the ScrollView, then the `scrollToEnd` method should not scroll anywhere.
**Code formatting**
Look around. Match the style of the rest of the codebase. See also the simple [style guide](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#style-guide).
For more info, see the ["Pull Requests" section of our "Contributing" guidelines](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#pull-requests).
Closes https://github.com/facebook/react-native/pull/12889
Reviewed By: javache
Differential Revision: D5289894
Pulled By: sahrens
fbshipit-source-id: df2e779ee855c1dea85d33649d754371ad244bca