New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add zIndex support #7825

Closed
wants to merge 19 commits into
base: master
from

Conversation

Projects
None yet
9 participants
@tuckerconnelly

tuckerconnelly commented May 29, 2016

Summary:

Adds zIndex support :)

Test Plan

Tested the following components by adding two of each, overlapping them, and setting a high zIndex on the first of the two:

ActivityIndicator
Image
MapView
Picker
ScrollView
Slider
Switch
Text
TextInput
View
WebView

Tested on Android 4.1 and iOS 8.4. Also tested updating zIndexes on Views in my own app.

ios activityindicator

android activityindicator

ios image

android image

android picker

ios picker

ios pickerios

ios scrollview

android scrollview

android view

ios view

ios slider

android slider

ios switch

android switch

ios text

android text

ios textinput

android textinput

android webview

screen shot 2016-05-29 at 7 01 38 pm

iOS seems to have a bug where zPosition is ignored when calling renderInContext (http://lists.apple.com/archives/cocoa-dev/2013/Jan/msg00084.html), so the test snapshots won't be z-indexed. If it's important enough I can look into another solution besides using zPosition.


iOS WebView was tough. Apparently RCTWebView is a subview? I set the zPosition on the superview in webViewDidFinishLoad, which seems a little hacky to me, so maybe someone can suggest a better solution :)

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost May 29, 2016

By analyzing the blame information on this pull request, we identified @mkonicek and @bestander to be potential reviewers.

ghost commented May 29, 2016

By analyzing the blame information on this pull request, we identified @mkonicek and @bestander to be potential reviewers.

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost May 29, 2016

@tuckerconnelly updated the pull request.

ghost commented May 29, 2016

@tuckerconnelly updated the pull request.

Show outdated Hide outdated React/Views/RCTViewManager.m Outdated
@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood May 31, 2016

Contributor

This looks promising, but I think the implementation on iOS needs to work by sorting the actual view order instead of adjusting the layer.zPosition.

(I also think you may have got the sign wrong on the zPosition anyway, as it appears that views with higher zIndex are being drawn behind views with lower zIndex, whereas according to the CSS spec "An element with greater stack order is always in front of an element with a lower stack order.")

Contributor

nicklockwood commented May 31, 2016

This looks promising, but I think the implementation on iOS needs to work by sorting the actual view order instead of adjusting the layer.zPosition.

(I also think you may have got the sign wrong on the zPosition anyway, as it appears that views with higher zIndex are being drawn behind views with lower zIndex, whereas according to the CSS spec "An element with greater stack order is always in front of an element with a lower stack order.")

@tuckerconnelly

This comment has been minimized.

Show comment
Hide comment
@tuckerconnelly

tuckerconnelly May 31, 2016

Nick, in the comment above:

iOS seems to have a bug where zPosition is ignored when calling renderInContext (http://lists.apple.com/archives/cocoa-dev/2013/Jan/msg00084.html), so the test snapshots won't be z-indexed.

Doesn't matter though 'cause zPosition won't work :P. Would bringSubviewToFront work?

Also, for Android, will bringToFront work with touch events?

tuckerconnelly commented May 31, 2016

Nick, in the comment above:

iOS seems to have a bug where zPosition is ignored when calling renderInContext (http://lists.apple.com/archives/cocoa-dev/2013/Jan/msg00084.html), so the test snapshots won't be z-indexed.

Doesn't matter though 'cause zPosition won't work :P. Would bringSubviewToFront work?

Also, for Android, will bringToFront work with touch events?

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood May 31, 2016

Contributor

iOS seems to have a bug where zPosition is ignored when calling renderInContext

Ah, that makes sense.

Doesn't matter though 'cause zPosition won't work :P. Would bringSubviewToFront work?

Yes, but we need to be very careful when messing with the view order so that subsequent updates don't end up removing the wrong view.

I think we need to figure out the best place to do the view sorting. Options are:

  1. In the view itself, inside the setReactSubviews method. That will mean storing the reactSubviews in an array and then sorting the views when they are added to the underlying UIView.subviews array.

  2. In the UIManager, so that views are sorted prior to being inserted into the view/shadowView

  3. On the JS side, so that they are already sorted by zIndex before they are sent over the bridge.

I'm not sure which of these is the best option, although 3) has the nice benefit that we could share the code between iOS and Android and avoid platform-specific hacks.

Also, for Android, will bringToFront work with touch events?

Sorry, I don't know anything about Android ¯_(ツ)_/¯

Contributor

nicklockwood commented May 31, 2016

iOS seems to have a bug where zPosition is ignored when calling renderInContext

Ah, that makes sense.

Doesn't matter though 'cause zPosition won't work :P. Would bringSubviewToFront work?

Yes, but we need to be very careful when messing with the view order so that subsequent updates don't end up removing the wrong view.

I think we need to figure out the best place to do the view sorting. Options are:

  1. In the view itself, inside the setReactSubviews method. That will mean storing the reactSubviews in an array and then sorting the views when they are added to the underlying UIView.subviews array.

  2. In the UIManager, so that views are sorted prior to being inserted into the view/shadowView

  3. On the JS side, so that they are already sorted by zIndex before they are sent over the bridge.

I'm not sure which of these is the best option, although 3) has the nice benefit that we could share the code between iOS and Android and avoid platform-specific hacks.

Also, for Android, will bringToFront work with touch events?

Sorry, I don't know anything about Android ¯_(ツ)_/¯

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood May 31, 2016

Contributor

Now I think about it, 3) probably isn't viable since it will affect the flexbox layout if we change the order prior to sending the views to native.

That means the order of shadowViews can't be changed based on zIndex, we can only change the order for UIViews.

Contributor

nicklockwood commented May 31, 2016

Now I think about it, 3) probably isn't viable since it will affect the flexbox layout if we change the order prior to sending the views to native.

That means the order of shadowViews can't be changed based on zIndex, we can only change the order for UIViews.

@tuckerconnelly

This comment has been minimized.

Show comment
Hide comment
@tuckerconnelly

tuckerconnelly May 31, 2016

UIManager seems like the simplest to me--if it was done in the setReactSubviews method I think it'd have to be done in all the components' setReactSubviews methods. I'll give it a shot :)

tuckerconnelly commented May 31, 2016

UIManager seems like the simplest to me--if it was done in the setReactSubviews method I think it'd have to be done in all the components' setReactSubviews methods. I'll give it a shot :)

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood May 31, 2016

Contributor

@tuckerconnelly I've got an idea how to approach this using setReactSubviews actually. I'll let you know if I can make it work.

Contributor

nicklockwood commented May 31, 2016

@tuckerconnelly I've got an idea how to approach this using setReactSubviews actually. I'll let you know if I can make it work.

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 2, 2016

Contributor

@tuckerconnelly I have a solution working for iOS. I'm just checking that it doesn't negatively affect performance.

Contributor

nicklockwood commented Jun 2, 2016

@tuckerconnelly I have a solution working for iOS. I'm just checking that it doesn't negatively affect performance.

ghost pushed a commit that referenced this pull request Jun 7, 2016

Implement CSS z-index for iOS
Summary:
This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons:

1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them.
2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable.

See #7825 for further discussion of this problem.

So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself.

It works as follows:

1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager.
2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of  `reactSubviews` by zIndex) and inserts the result into the view.
3.  If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and  `didUpdateReactSubviews` is called again.

To demonstrate it working, I've modified the UIExplorer example from #7825

Reviewed By: javache

Differential Revision: D3365717

fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 7, 2016

Contributor

@tuckerconnelly OK, I've landed zIndex support for iOS: d64368b

You should be able to rebase your PR on top to add Android support.

Contributor

nicklockwood commented Jun 7, 2016

@tuckerconnelly OK, I've landed zIndex support for iOS: d64368b

You should be able to rebase your PR on top to add Android support.

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 7, 2016

Contributor

Cc: @dmmiller Dave, can you review the Android implementation here? I don't know the platform well enough to judge if this is an appropriate solution, or if we need to implement something like what I've done on iOS.

Contributor

nicklockwood commented Jun 7, 2016

Cc: @dmmiller Dave, can you review the Android implementation here? I don't know the platform well enough to judge if this is an appropriate solution, or if we need to implement something like what I've done on iOS.

@tuckerconnelly

This comment has been minimized.

Show comment
Hide comment
@tuckerconnelly

tuckerconnelly Jun 7, 2016

DUDE YEAH! I can tomorrow

tuckerconnelly commented Jun 7, 2016

DUDE YEAH! I can tomorrow

@syzer

This comment has been minimized.

Show comment
Hide comment
@syzer

syzer commented Jun 7, 2016

👍

@dmmiller

This comment has been minimized.

Show comment
Hide comment
@dmmiller

dmmiller Jun 9, 2016

Contributor

Is this on every single view or are some exempted for some reason? In general, the core seems correct. I'm a little sad about doing this with an interface and 10 copy/pasted lines in every single view. This also won't scale if we have views that are purely native and not wrapped by react native. Is there a way to maybe do this with an annotation on the view (that addresses the first part, but not the second)?

Contributor

dmmiller commented Jun 9, 2016

Is this on every single view or are some exempted for some reason? In general, the core seems correct. I'm a little sad about doing this with an interface and 10 copy/pasted lines in every single view. This also won't scale if we have views that are purely native and not wrapped by react native. Is there a way to maybe do this with an annotation on the view (that addresses the first part, but not the second)?

@tuckerconnelly

This comment has been minimized.

Show comment
Hide comment
@tuckerconnelly

tuckerconnelly Jun 9, 2016

Yeah I didn't like the interface either. I can't really imagine a way to do it with annotations without stepping out of ViewManager-manages-View pattern, but I'm not a pro with Java :)

What if we created a generic View and have every subclass of View contain a reference to the android component. So something like:

public class ReactGenericView<T extends android.view.View> {
  private @Nullable float mZIndex;

  public void setZIndex(float zIndex) {
    mZIndex = zIndex;
  }

  public float getZIndex() {
    return mZIndex;
  }
  // Other future props
  // Could also put borderRadius, etc. in here
  public abstract T getComponent()
}

class ReactImageView extends ReactGenericView<GenericDraweeView> {
  // Stuff specific to Images
  @Override
  public GenericDraweeView getComponent() {
    // return lazily-initialized GenericDraweeView
  }
}

class ReactImageManager {
  @ReactProp(name = "tintColor", customType = "Color")
  public void setTintColor(ReactImageView view, @Nullable Integer tintColor) {
    if (tintColor == null) {
      view.getComponent().clearColorFilter();
    } else {
      view.getComponent().setColorFilter(tintColor, Mode.SRC_IN);
    }
  }
}

That's a pretty big change though.

Re: purely native views, I could put a default in to treat them as zIndex: 0, and if they wanted to set their own zIndex, they could implement the interface (or extend GenericView) and React would pick up on it.

Edit: Actually that wouldn't work with the interface because it wouldn't re-order the siblings when set. It would work with GenericView though, if the siblings were re-ordered on setZIndex.

tuckerconnelly commented Jun 9, 2016

Yeah I didn't like the interface either. I can't really imagine a way to do it with annotations without stepping out of ViewManager-manages-View pattern, but I'm not a pro with Java :)

What if we created a generic View and have every subclass of View contain a reference to the android component. So something like:

public class ReactGenericView<T extends android.view.View> {
  private @Nullable float mZIndex;

  public void setZIndex(float zIndex) {
    mZIndex = zIndex;
  }

  public float getZIndex() {
    return mZIndex;
  }
  // Other future props
  // Could also put borderRadius, etc. in here
  public abstract T getComponent()
}

class ReactImageView extends ReactGenericView<GenericDraweeView> {
  // Stuff specific to Images
  @Override
  public GenericDraweeView getComponent() {
    // return lazily-initialized GenericDraweeView
  }
}

class ReactImageManager {
  @ReactProp(name = "tintColor", customType = "Color")
  public void setTintColor(ReactImageView view, @Nullable Integer tintColor) {
    if (tintColor == null) {
      view.getComponent().clearColorFilter();
    } else {
      view.getComponent().setColorFilter(tintColor, Mode.SRC_IN);
    }
  }
}

That's a pretty big change though.

Re: purely native views, I could put a default in to treat them as zIndex: 0, and if they wanted to set their own zIndex, they could implement the interface (or extend GenericView) and React would pick up on it.

Edit: Actually that wouldn't work with the interface because it wouldn't re-order the siblings when set. It would work with GenericView though, if the siblings were re-ordered on setZIndex.

@dmmiller

This comment has been minimized.

Show comment
Hide comment
@dmmiller

dmmiller Jun 9, 2016

Contributor

@lexs do you know a good way to do this with annotations?

Contributor

dmmiller commented Jun 9, 2016

@lexs do you know a good way to do this with annotations?

@lexs

This comment has been minimized.

Show comment
Hide comment
@lexs

lexs Jun 9, 2016

Member

We talked about the Android side internally and have a few wishes.

Instead of forcing each view to implement an interface can we have a look-aside map like: WeakHashMap<View, Integer>. Note that this will also require changing both impls to use int instead of float. The reason to use Integer here is that we can avoid boxing (and instead relying on the internal Java cache for small Integers), there is no such cache for floats. Using integers is also the css spec: https://developer.mozilla.org/en/docs/Web/CSS/z-index

We'd also like to move to a model where addChild() doesn't require sorting children if none of them have a z-index because we're afraid this might hurt perf. As I'd really like to see this land I don't think we need to do it in this PR but we (you or us internally) should look into this in the future depending on how inefficient the current implementation is. We have a few ideas on how to do this by for example keeping track of which ViewGroups contain z-indexed children and skipping sorting if we know they contain no z-children.

Member

lexs commented Jun 9, 2016

We talked about the Android side internally and have a few wishes.

Instead of forcing each view to implement an interface can we have a look-aside map like: WeakHashMap<View, Integer>. Note that this will also require changing both impls to use int instead of float. The reason to use Integer here is that we can avoid boxing (and instead relying on the internal Java cache for small Integers), there is no such cache for floats. Using integers is also the css spec: https://developer.mozilla.org/en/docs/Web/CSS/z-index

We'd also like to move to a model where addChild() doesn't require sorting children if none of them have a z-index because we're afraid this might hurt perf. As I'd really like to see this land I don't think we need to do it in this PR but we (you or us internally) should look into this in the future depending on how inefficient the current implementation is. We have a few ideas on how to do this by for example keeping track of which ViewGroups contain z-indexed children and skipping sorting if we know they contain no z-children.

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 10, 2016

Contributor

We'd also like to move to a model where addChild() doesn't require sorting children if none of them have a z-index because we're afraid this might hurt perf

FWIW, the iOS implementation has this optimisation. I currently do it in a fairly naive way – instead of keeping track as the views are added, I just do a single pass through the views to see if any has a non-zero zIndex before I sort them – but that means the common case is O(n) instead of O(n log n) so it still seems worth doing.

Contributor

nicklockwood commented Jun 10, 2016

We'd also like to move to a model where addChild() doesn't require sorting children if none of them have a z-index because we're afraid this might hurt perf

FWIW, the iOS implementation has this optimisation. I currently do it in a fairly naive way – instead of keeping track as the views are added, I just do a single pass through the views to see if any has a non-zero zIndex before I sort them – but that means the common case is O(n) instead of O(n log n) so it still seems worth doing.

@mkonicek

This comment has been minimized.

Show comment
Hide comment
@mkonicek

mkonicek Jun 14, 2016

Contributor

@tuckerconnelly,@lexs What's the status? Does this need review or changes?

Contributor

mkonicek commented Jun 14, 2016

@tuckerconnelly,@lexs What's the status? Does this need review or changes?

@dmmiller

This comment has been minimized.

Show comment
Hide comment
@dmmiller

dmmiller Jun 15, 2016

Contributor

It needs to be rebased and updated.

Contributor

dmmiller commented Jun 15, 2016

It needs to be rebased and updated.

@tuckerconnelly

This comment has been minimized.

Show comment
Hide comment
@tuckerconnelly

tuckerconnelly Jun 15, 2016

Okay I started the look-aside map impl (genius, btw, @lexs 👍), but I can't get it to work when the view is added (only when setting the zIndex after the view is added). Can you @lexs or someone else take a look and let me know what I'm doing wrong?

tuckerconnelly commented Jun 15, 2016

Okay I started the look-aside map impl (genius, btw, @lexs 👍), but I can't get it to work when the view is added (only when setting the zIndex after the view is added). Can you @lexs or someone else take a look and let me know what I'm doing wrong?

@tuckerconnelly

This comment has been minimized.

Show comment
Hide comment
@tuckerconnelly

tuckerconnelly Jun 23, 2016

Alright it's up. I also added the optimization to check if there are any non-zero z-indexes before sorting 😃

tuckerconnelly commented Jun 23, 2016

Alright it's up. I also added the optimization to check if there are any non-zero z-indexes before sorting 😃

@lexs

This comment has been minimized.

Show comment
Hide comment
@lexs

lexs Jun 23, 2016

Member

@tuckerconnelly Thanks, I'll import this now and test it internally for perf regressions. I'll merge it on Monday if everything goes well :)

Member

lexs commented Jun 23, 2016

@tuckerconnelly Thanks, I'll import this now and test it internally for perf regressions. I'll merge it on Monday if everything goes well :)

@lexs

This comment has been minimized.

Show comment
Hide comment
@lexs
Member

lexs commented Jun 23, 2016

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Jun 23, 2016

Thanks for importing. If you are an FB employee go to Phabricator to review.

ghost commented Jun 23, 2016

Thanks for importing. If you are an FB employee go to Phabricator to review.

rozele pushed a commit to Microsoft/react-native-windows that referenced this pull request Jun 28, 2016

Implement CSS z-index for iOS
Summary:
This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons:

1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them.
2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable.

See facebook/react-native#7825 for further discussion of this problem.

So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself.

It works as follows:

1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager.
2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of  `reactSubviews` by zIndex) and inserts the result into the view.
3.  If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and  `didUpdateReactSubviews` is called again.

To demonstrate it working, I've modified the UIExplorer example from facebook/react-native#7825

Reviewed By: javache

Differential Revision: D3365717

fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
@lexs

This comment has been minimized.

Show comment
Hide comment
@lexs
Member

lexs commented Jun 29, 2016

1 similar comment
@lexs

This comment has been minimized.

Show comment
Hide comment
@lexs
Member

lexs commented Jun 29, 2016

@facebook-github-bot shipit

@ghost ghost added the Import Started label Jun 29, 2016

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Jun 29, 2016

Thanks for importing. If you are an FB employee go to Phabricator to review.

ghost commented Jun 29, 2016

Thanks for importing. If you are an FB employee go to Phabricator to review.

@ghost ghost closed this in 3d3b067 Jun 29, 2016

@bestander

This comment has been minimized.

Show comment
Hide comment
@bestander

bestander Jun 30, 2016

Contributor

I am a bit confused about the changed images for the iOS snapshot tests.
How are they related to the java change?

Contributor

bestander commented Jun 30, 2016

I am a bit confused about the changed images for the iOS snapshot tests.
How are they related to the java change?

@bestander

This comment has been minimized.

Show comment
Hide comment
@bestander

bestander Jun 30, 2016

Contributor

@lexs, the test was failing on the CI for the PR https://travis-ci.org/facebook/react-native/builds/137840201, be careful :)

Contributor

bestander commented Jun 30, 2016

@lexs, the test was failing on the CI for the PR https://travis-ci.org/facebook/react-native/builds/137840201, be careful :)

bestander added a commit to bestander/react-native that referenced this pull request Jun 30, 2016

Revert PR-7825 snapshot changes
Tests got broken after facebook#7825, reverting changes

Test Plan:
./scritps/objc-test.sh

ghost pushed a commit that referenced this pull request Jun 30, 2016

Revert PR-7825 snapshot changes
Summary:
Tests got broken after #7825, reverting changes
Closes #8508

Differential Revision: D3503439

Pulled By: bestander

fbshipit-source-id: 95b9283371654265234d975e1b0df540f4ef55fa
@tuckerconnelly

This comment has been minimized.

Show comment
Hide comment
@tuckerconnelly

tuckerconnelly Jun 30, 2016

Picked the wrong yours/theirs in my revert/rebase. Had a hard time getting the Snapshot Test Cases to run again so just ignored it :P I can try to get them fixed up tomorrow morning

tuckerconnelly commented Jun 30, 2016

Picked the wrong yours/theirs in my revert/rebase. Had a hard time getting the Snapshot Test Cases to run again so just ignored it :P I can try to get them fixed up tomorrow morning

@bestander

This comment has been minimized.

Show comment
Hide comment
@bestander

bestander Jun 30, 2016

Contributor

No worries, fixd it now bb0fda7

Contributor

bestander commented Jun 30, 2016

No worries, fixd it now bb0fda7

rozele pushed a commit to Microsoft/react-native-windows that referenced this pull request Jul 6, 2016

Tucker Connelly Facebook Github Bot 3
Add zIndex support
Summary:
Adds zIndex support :)

**Test Plan**

Tested the following components by adding two of each, overlapping them, and setting a high zIndex on the first of the two:

ActivityIndicator
Image
MapView
Picker
ScrollView
Slider
Switch
Text
TextInput
View
WebView

Tested on Android 4.1 and iOS 8.4. Also tested updating zIndexes on Views in my own app.

<img width="359" alt="ios activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633473/88f842cc-257b-11e6-8539-c41c0b179f80.png">
<img width="330" alt="android activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633475/88f95784-257b-11e6-80c0-2bf3ed836503.png">
<img width="357" alt="ios image" src="https://cloud.githubusercontent.com/assets/4349082/15633474/88f93d80-257b-11e6-9e54-4ff8e4d25f71.png">
<img width="340" alt="android image" src="https://cloud.githubusercontent.com/assets/4349082/15633478/88fd2788-257b-11e6-8c80-29078e65e808.png">
<img width="342" alt="android picker" src="ht
Closes facebook/react-native#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658

rozele pushed a commit to Microsoft/react-native-windows that referenced this pull request Jul 6, 2016

Revert PR-7825 snapshot changes
Summary:
Tests got broken after facebook/react-native#7825, reverting changes
Closes facebook/react-native#8508

Differential Revision: D3503439

Pulled By: bestander

fbshipit-source-id: 95b9283371654265234d975e1b0df540f4ef55fa

samerce added a commit to iodine/react-native that referenced this pull request Aug 23, 2016

Implement CSS z-index for iOS
Summary:
This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons:

1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them.
2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable.

See facebook#7825 for further discussion of this problem.

So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself.

It works as follows:

1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager.
2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of  `reactSubviews` by zIndex) and inserts the result into the view.
3.  If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and  `didUpdateReactSubviews` is called again.

To demonstrate it working, I've modified the UIExplorer example from facebook#7825

Reviewed By: javache

Differential Revision: D3365717

fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa

samerce added a commit to iodine/react-native that referenced this pull request Aug 23, 2016

Add zIndex support
Summary:
Adds zIndex support :)

**Test Plan**

Tested the following components by adding two of each, overlapping them, and setting a high zIndex on the first of the two:

ActivityIndicator
Image
MapView
Picker
ScrollView
Slider
Switch
Text
TextInput
View
WebView

Tested on Android 4.1 and iOS 8.4. Also tested updating zIndexes on Views in my own app.

<img width="359" alt="ios activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633473/88f842cc-257b-11e6-8539-c41c0b179f80.png">
<img width="330" alt="android activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633475/88f95784-257b-11e6-80c0-2bf3ed836503.png">
<img width="357" alt="ios image" src="https://cloud.githubusercontent.com/assets/4349082/15633474/88f93d80-257b-11e6-9e54-4ff8e4d25f71.png">
<img width="340" alt="android image" src="https://cloud.githubusercontent.com/assets/4349082/15633478/88fd2788-257b-11e6-8c80-29078e65e808.png">
<img width="342" alt="android picker" src="ht
Closes facebook#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658

samerce added a commit to iodine/react-native that referenced this pull request Aug 23, 2016

Revert PR-7825 snapshot changes
Summary:
Tests got broken after facebook#7825, reverting changes
Closes facebook#8508

Differential Revision: D3503439

Pulled By: bestander

fbshipit-source-id: 95b9283371654265234d975e1b0df540f4ef55fa

mpretty-cyro pushed a commit to HomePass/react-native that referenced this pull request Aug 25, 2016

Implement CSS z-index for iOS
Summary:
This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons:

1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them.
2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable.

See facebook#7825 for further discussion of this problem.

So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself.

It works as follows:

1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager.
2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of  `reactSubviews` by zIndex) and inserts the result into the view.
3.  If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and  `didUpdateReactSubviews` is called again.

To demonstrate it working, I've modified the UIExplorer example from facebook#7825

Reviewed By: javache

Differential Revision: D3365717

fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa

mpretty-cyro pushed a commit to HomePass/react-native that referenced this pull request Aug 25, 2016

Tucker Connelly Morgan Pretty
Add zIndex support
Summary:
Adds zIndex support :)

**Test Plan**

Tested the following components by adding two of each, overlapping them, and setting a high zIndex on the first of the two:

ActivityIndicator
Image
MapView
Picker
ScrollView
Slider
Switch
Text
TextInput
View
WebView

Tested on Android 4.1 and iOS 8.4. Also tested updating zIndexes on Views in my own app.

<img width="359" alt="ios activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633473/88f842cc-257b-11e6-8539-c41c0b179f80.png">
<img width="330" alt="android activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633475/88f95784-257b-11e6-80c0-2bf3ed836503.png">
<img width="357" alt="ios image" src="https://cloud.githubusercontent.com/assets/4349082/15633474/88f93d80-257b-11e6-9e54-4ff8e4d25f71.png">
<img width="340" alt="android image" src="https://cloud.githubusercontent.com/assets/4349082/15633478/88fd2788-257b-11e6-8c80-29078e65e808.png">
<img width="342" alt="android picker" src="ht
Closes facebook#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658

mpretty-cyro pushed a commit to HomePass/react-native that referenced this pull request Aug 25, 2016

Revert PR-7825 snapshot changes
Summary:
Tests got broken after facebook#7825, reverting changes
Closes facebook#8508

Differential Revision: D3503439

Pulled By: bestander

fbshipit-source-id: 95b9283371654265234d975e1b0df540f4ef55fa

berrytj added a commit to mdcollab/react-native that referenced this pull request Nov 8, 2016

Add zIndex support
Summary:
Adds zIndex support :)

**Test Plan**

Tested the following components by adding two of each, overlapping them, and setting a high zIndex on the first of the two:

ActivityIndicator
Image
MapView
Picker
ScrollView
Slider
Switch
Text
TextInput
View
WebView

Tested on Android 4.1 and iOS 8.4. Also tested updating zIndexes on Views in my own app.

<img width="359" alt="ios activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633473/88f842cc-257b-11e6-8539-c41c0b179f80.png">
<img width="330" alt="android activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633475/88f95784-257b-11e6-80c0-2bf3ed836503.png">
<img width="357" alt="ios image" src="https://cloud.githubusercontent.com/assets/4349082/15633474/88f93d80-257b-11e6-9e54-4ff8e4d25f71.png">
<img width="340" alt="android image" src="https://cloud.githubusercontent.com/assets/4349082/15633478/88fd2788-257b-11e6-8c80-29078e65e808.png">
<img width="342" alt="android picker" src="ht
Closes facebook#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658

berrytj added a commit to mdcollab/react-native that referenced this pull request Jan 22, 2017

Add zIndex support
Summary:
Adds zIndex support :)

**Test Plan**

Tested the following components by adding two of each, overlapping them, and setting a high zIndex on the first of the two:

ActivityIndicator
Image
MapView
Picker
ScrollView
Slider
Switch
Text
TextInput
View
WebView

Tested on Android 4.1 and iOS 8.4. Also tested updating zIndexes on Views in my own app.

<img width="359" alt="ios activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633473/88f842cc-257b-11e6-8539-c41c0b179f80.png">
<img width="330" alt="android activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633475/88f95784-257b-11e6-80c0-2bf3ed836503.png">
<img width="357" alt="ios image" src="https://cloud.githubusercontent.com/assets/4349082/15633474/88f93d80-257b-11e6-9e54-4ff8e4d25f71.png">
<img width="340" alt="android image" src="https://cloud.githubusercontent.com/assets/4349082/15633478/88fd2788-257b-11e6-8c80-29078e65e808.png">
<img width="342" alt="android picker" src="ht
Closes facebook#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658

This issue was closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment