react-native-draggable-flatlist icon indicating copy to clipboard operation
react-native-draggable-flatlist copied to clipboard

iOS: Item floating away on long press, preventing drag and drop to work correctly

Open TommyBez opened this issue 4 years ago • 8 comments
trafficstars

Describe the bug When pressing on an item to start dragging, the item moves away from the touchpoint and drag doesn't work. The issue is iOS only and appears randomly when I'm in debug, whereas is always present in my production build. https://user-images.githubusercontent.com/65722261/127123769-296c613f-f6d8-48d2-9c7d-23ca9c310218.MP4

To Reproduce Here is my implementation code:

const ItemSeparatorComponent = () => <Spacer size={Theme.Sizes.spacing.lg}/>
const FooterComponent = (<Spacer size={SHARE_CTA_SPACER}/>)
const keyExtractor = ([key]) => key

const ItemPlaceholder = () => (
 <Row >
    <Column flex={0}>
      <Placeholder
        borderRadius={10}
        height={10}
        width={10}
      />
    </Column>
    <Column>
      <Placeholder
        height={22}
        width={100}
      />
      <Spacer size={2}/>
      <Placeholder
        height={16}
        width={210}
      />
    </Column>
    <Column flex={0}>
      <Placeholder
        borderRadius={13}
        height={26}
        width={42}
      />
    </Column>
  </Row>)

const ListEmptyComponent = (<View style={{ marginHorizontal: Theme.Sizes.margin.md } }>
  <ItemPlaceholder/>
  <Spacer size={Theme.Sizes.spacing.lg}/>
  <ItemPlaceholder/>
  <Spacer size={Theme.Sizes.spacing.lg}/>
  <ItemPlaceholder/>
  <Spacer size={Theme.Sizes.spacing.lg}/>
  <ItemPlaceholder/>
  <Spacer size={Theme.Sizes.spacing.lg}/>
  <ItemPlaceholder/>
</View>)

  const ListHeaderComponent = useMemo(() => {
    const editCode = () => {}
    const showLandingPage = () => {}
    return (
      <View style={styles.horizontalMargin}>
        <Spacer size={Theme.Sizes.spacing.sm}/>
        <Header
          style={styles.header}
          title={Localization.translate('text_edit')}
          subtitle={Localization.translate('screen_referral__update_landing_page--subtitle')}
        />
        <Column noGutter>
          <Row alignBottom noGutter left>
            <TicketIcon
              color={Theme.Palette.violetBlue500}
              size={Theme.Sizes.iconSize.xxs}
            />
            <ThemedText style={styles.terms}>
              <Link style={styles.link} onPress={showLandingPage}>
                {Localization.translate('landing_page_tutorial_create-cta--show')}
              </Link>
            </ThemedText>
          </Row>
          <Spacer size={Theme.Sizes.spacing.xl}/>
          <Row>
            { !loading && code && <InputShowcase
              mainText={code}
              label={Localization.translate('screen_referral__code_page_label_code')}
              icon={Icon.Names.create}
              iconColor={Theme.Palette.eerieBlack800}
              onPressIcon={editCode}
            />}
            {loading && <InputShowcase.Placeholder />}

          </Row>
          <Spacer size={Theme.Sizes.spacing.xl}/>
          <SectionList.Header containerStyle={styles.sectionHeader} text={Localization.translate('screen_referral__update_landing_page__list__title')}/>
          <Spacer size={Theme.Sizes.spacing.md}/>
        </Column>
      </View>)
  }, [loading, code, componentId, promoCode, url])

  const renderItem = useCallback(({ item: [key, value], drag, isActive }) => {
    const opacityStyle = { opacity: isActive ? 0.2 : 1 }

    return <Row key={key} style={[styles.row, opacityStyle]} >
      <Column flex={1}>
        <TouchableOpacity style={styles.dragItem} onLongPress={drag}>
          <Column flex={0}>
            <Icon name={Icon.Names.reorderTwoOutline} size={Theme.Sizes.spacing.mdp} color={Theme.Palette.eerieBlack400}/>
          </Column>
          <Column>
            <Text style={styles.itemTitle}>{Localization.translate(`screen_referral__update_landing_page__item__title--${key}`)}</Text>
            <Text style={styles.itemSubTitle}>{Localization.translate(`screen_referral__update_landing_page__item__subtitle--${key}`)}</Text>
          </Column>
        </TouchableOpacity>
      </Column>

      <Column flex={0}>
        <Switch onValueChange={ newValue => onSwitchToggle({ key, value: newValue }) } value={value}/>
      </Column>
    </Row>
  }, [onSwitchToggle])
  return (<>
    <DraggableFlatList
      keyExtractor={keyExtractor}
      dragItemOverflow={false}
      ListHeaderComponent={ListHeaderComponent}
      ItemSeparatorComponent={ItemSeparatorComponent}
      data={sections}
      ListFooterComponent={FooterComponent}
      renderItem={renderItem}
      showsVerticalScrollIndicator={false}
      ListEmptyComponent={ListEmptyComponent}
      onDragEnd={onListOrdered}
      activationDistance={1}
    />
    <ShareCodeCTA loading={loading} code={code} url={url}/>
  </>
  )
}

export default UpdateLandingPage

const styles = StyleSheet.create({
  dragItem: {
    alignItems: 'flex-start',
    display: 'flex',
    flexDirection: 'row',
    paddingLeft: Theme.Sizes.padding.md
  },
  header: {
    marginHorizontal: -Theme.Sizes.margin.md
  },
  horizontalMargin: {
    marginHorizontal: Theme.Sizes.spacing.md
  },
  itemSubTitle: {
    ...Theme.Typography.caption1,
    color: Theme.Palette.eerieBlack600
  },
  itemTitle: {
    ...Theme.Typography.callout,
    ...Theme.FontFamily.medium,
    color: Theme.Palette.eerieBlack800
  },
  link: {
    color: Theme.Palette.violetBlue500
  },
  row: { marginRight: Theme.Sizes.margin.md },
  sectionHeader: {
    paddingHorizontal: 0
  },
  terms: {
    alignContent: 'center',
    marginLeft: Theme.Sizes.margin.md - Theme.Sizes.margin.xs,
    marginTop: Theme.Sizes.margin.xs
  }
})

Platform & Dependencies

  • Platform: iOS
  • React Native: 0.63.4
  • Reanimated version: 2.0.0
  • React Native Gesture Handler version: 1.10.3

TommyBez avatar Jul 27 '21 08:07 TommyBez

seems to be something similar to this one #70

TommyBez avatar Jul 27 '21 10:07 TommyBez

Any update on this one? I could add that, whereas the bug is ever-present in production's build, it pops up in debug only if the app has been open from the launcher, i.e. it disappears if I reload the app from the terminal.

TommyBez avatar Aug 04 '21 09:08 TommyBez

same, :facepalm: any updates?

zedelashvililevani avatar Aug 09 '21 14:08 zedelashvililevani

I'm guessing this has to do with the fact that your list header is changing size. Can you try updating layoutInvalidationKey with loading, code, and anything else that affects your header size?

computerjazz avatar Sep 01 '21 16:09 computerjazz

@TommasoTate did u manage to solve it? i am having the same issue. Is weird because if I reload the app from the terminal a few times it works.

brunomartinezciompi avatar Sep 07 '21 14:09 brunomartinezciompi

Using "react-native-reanimated": "1.13.3" resolved issue for me.

ithebk avatar Sep 19 '21 11:09 ithebk

Using "react-native-reanimated": "1.13.3" resolved issue for me.

Yes! I had this issue after updating dependencies and fixed it by downgrading react-native-reanimated. v1.13.3 is the latest working version with draggable flatlist. v2 has breaking changes.

msvickylau avatar Sep 29 '21 16:09 msvickylau

I am getting the same behaviour.

Here is a screen recording demonstrating the problem (on iOS, [email protected]):

https://github.com/computerjazz/react-native-draggable-flatlist/assets/6492155/b8ecb2bb-6d04-40e6-ad80-edfe7646b60b

jlmurphysa avatar May 13 '24 09:05 jlmurphysa