Skip to content

Commit

Permalink
Fix: Pressable regular border radius rendering on iOS on old arch (#3279
Browse files Browse the repository at this point in the history
)

## Description

<!--
Description and motivation for this PR.

Include 'Fixes #<number>' if this is fixing some issue.
-->

Fixes #3137 

This PR fixes **regular** border rendering for gesture handler buttons
on old architecture. React Native
[determines](https://github.com/facebook/react-native/blob/main/packages/react-native/React/Views/RCTViewManager.m#L370-L377)
how native component handles border radius by checking if it implements
`setBorderRadius` method. Previously, there was not a mechanism to scale
border radius down and it relied purely on how the iOS handles it for
large values.

It is done similarly to how [react
native](https://github.com/facebook/react-native/blob/main/packages/react-native/React/Views/RCTView.m#L670-L734)
calculates that but for regular borders only it becomes much simpler.


![example](https://github.com/user-attachments/assets/377a8f5e-af1d-4095-a193-62715f860c70)

## Test plan

<!--
Describe how did you test this change here.
-->

<details>

<summary>Test code</summary>

```ts
import React from 'react';
import {
  View,
  Text,
  SafeAreaView,
  Pressable as RNPressable,
} from 'react-native';

import {
  Pressable as RNGHPressable,
  GestureHandlerRootView,
} from 'react-native-gesture-handler';

const examples = new Array(16).fill(0).map((_, i) => i);

function DefaultPressables() {
  return (
    <View>
      <Text>RN</Text>
      <View style={{ gap: 8 }}>
        {
          examples.map((i) => (
            <RNPressable
              key={`rn_${i}`}
              style={[
                buttonStyle,
                {
                  backgroundColor: 'lightgreen',
                  borderRadius: i,
                },
              ]}>
              <Text>{i}</Text>
            </RNPressable>
          ))
        }

        <RNPressable
          style={[
            buttonStyle,
            {
              backgroundColor: 'lightgreen',
              borderRadius: 999,
            },
          ]}>
          <Text>999</Text>
        </RNPressable>
      </View>
    </View>
  )
}

function GHPressables() {
  return (
    <View>
      <Text>RNGH</Text>
      <View style={{ gap: 8 }}>
      {
          examples.map((i) => (
            <RNGHPressable
              key={`rngh_${i}`}
              style={[
                buttonStyle,
                {
                  backgroundColor: 'lightgreen',
                  borderRadius: i,
                },
              ]}>
              <Text>{i}</Text>
            </RNGHPressable>
          ))
        }

        <RNGHPressable
          style={[
            buttonStyle,
            {
              backgroundColor: 'lightgreen',
              borderRadius: 999,
            },
          ]}>
          <Text>{999}</Text>
        </RNGHPressable>
      </View>
    </View>
  )
}


export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <SafeAreaView>
        <View style={{ padding: 16, gap: 8, flexDirection: 'row' }}>
          <DefaultPressables />
          <GHPressables />
        </View>
      </SafeAreaView>
    </GestureHandlerRootView>
  );
}

const buttonStyle = {
  width: 32,
  height: 32,
  alignItems: 'center',
  justifyContent: 'center',
};
```

</details>
  • Loading branch information
coado authored Dec 12, 2024
1 parent 56c3351 commit 466d4e5
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions apple/RNGestureHandlerButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* Insets used when hit testing inside this view.
*/
@property (nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;
@property (nonatomic, assign) CGFloat borderRadius;
@property (nonatomic) BOOL userEnabled;

#if TARGET_OS_OSX && RCT_NEW_ARCH_ENABLED
Expand Down
23 changes: 23 additions & 0 deletions apple/RNGestureHandlerButton.mm
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,29 @@ - (RNGHUIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
}
return inner;
}

- (void)setBorderRadius:(CGFloat)radius
{
if (_borderRadius == radius) {
return;
}

_borderRadius = radius;
[self.layer setNeedsDisplay];
}

- (void)displayLayer:(CALayer *)layer
{
if (CGSizeEqualToSize(layer.bounds.size, CGSizeZero)) {
return;
}

const CGFloat radius = MAX(0, _borderRadius);
const CGSize size = self.bounds.size;
const CGFloat scaleFactor = RCTZeroIfNaN(MIN(1, size.width / (2 * radius)));
const CGFloat currentBorderRadius = radius * scaleFactor;
layer.cornerRadius = currentBorderRadius;
}
#endif

#if TARGET_OS_OSX && RCT_NEW_ARCH_ENABLED
Expand Down

0 comments on commit 466d4e5

Please sign in to comment.