Can't change pitch value on MapView or Camera - react-native

I've just switch from react-native-maps-osmdroid to react-native-mapbox-gl and havn't succeed to change pitch yet.
I've tried to set pitch in differents ways :
- directly on MapView component
- on Camera component with props "pitch" and "followPitch"
- on Camera component with props "defaultSettings"
- with ref on Camera and call this.camera.setCamera()
However none of this ways seems to work, the only way that I succeed to change pitch is from the app with three fingers.
<MapboxGL.MapView style={{ flex: 1 }}>
<MapboxGL.Camera
followPitch={15}
zoomLevel={16}
followUserLocation
/>
<MapboxGL.UserLocation />
</MapboxGL.MapView>
No error message whatever the way I change pitch but map don't change.
Someone know how to programatically change pitch?

Looks like set followUserLocation to true overide others settings (like centerCoordinates, pitch, heading).
I probably need to handle Camera movement by myself to follow user with pitch.
Let me know if you find another solution.

Related

How can I use react-native-gesture-handler to handle react-native-skia touches inside a ScrollView?

I have a ScrollView containing several graphs made with react-native-skia. The graphs are interactable, i.e. I can touch them and move an indicator on the graph along the x-axis of the graph.
My issue is that the whenever the ScrollView events fire (i.e. we scroll up/down), then the graph touch events are ignored which makes for bad UX.
Demo:
Here's a Snack with a reproducible demo: https://snack.expo.dev/#jorundur/supportive-raisins
FYI: For some reason for me the Canvas disappears after 1 second in the Snack, but if you make any change in the file and save (such add a newline somewhere), then it appears. It's fine if you run this locally. But that's some other problem we can ignore for the purpose of this discussion.
Description:
The demo is a react-native ScrollView large enough to make sure we have to scroll, the top component is a graph using react-native-skia. If we drag the cursor in the graph around, then the UX gets bad pretty quickly as the graph touch events seem to be ignored as soon as any vertical scrolling happens. I've tried playing around with ScrollView from react-native-gesture-handler but without luck.
To me, the expected behaviour would be for the graph to be interactable even while scrolling. I.e. if I'm pressing the graph and move my finger diagonally up/down I would expect the ScrollView to scroll and the graph cursor also to change its position accordingly. (I say diagonally since a straight vertical movement wouldn't change the cursor position in this graph.)
Much appreciated if anyone has any ideas on how to solve this! I couldn't work out how to do it via GestureDetector from react-native-gesture-handler like I've heard suggested.
Possible solution (?):
What I think I need to do is remove the onTouch={touchHandler} which I'm using currently in the react-native-skia Canvas component and instead get those touches via gesture detection from react-native-gesture-handler. I then need to make those gestures work simultaneously with the parent ScrollViews scroll event gestures. I've not had any luck implementing that unfortunately.
The solution was to do the following:
Don't use onTouch on Canvas, instead detect gestures via react-native-gesture-handler
Create a gesture and add a ref to it
Add the simultaneousHandlers prop to the ScrollView and use the ref there
This tells the ScrollView that its events should not be blocked by the touch events from the ref
To reiterate, what I wanted to do was to have the touch events of a ScrollView work simultaneously with touch events from a react-native-skia Canvas child component.
Code (relevant bits):
import * as React from 'react';
import {
GestureHandlerRootView,
ScrollView // Note that this is not imported from react-native
} from 'react-native-gesture-handler';
const App = () => {
// Create ref for the ScrollView to know what other gestures it should work simultaneously with.
// My use case required pan but this can be swapped for other gestures.
const panGestureRef = React.useRef<GestureType>(Gesture.Pan());
// The logic that used to be in `onTouch` on the Canvas is now here
const panGesture = Gesture.Pan()
.onChange((e) => {
// Do stuff, also use the other callbacks available as needed
})
.withRef(panGestureRef);
return (
<GestureHandlerRootView style={{ flex: 1 }}>{/* Don't forget this! It should be at the root of your project. */}
<ScrollView simultaneousHandlers={[panGestureRef]}>
<GestureDetector gesture={panGesture}>
<Canvas style={{ width: 200, height: 200 }}>
{/* Your interactive react-native-skia magic */}
</Canvas>
</GestureDetector>
</ScrollView>
</GestureHandlerRootView>
);
};
export default App;

How can I alter FontAwesomeIcon properties outside the initial <FontAwesomeIcon /> call in React Native?

I currently have a modal where the user can pick from a large flatlist of icons. All have size: '45' and color: 'white'. When a user selects an icon, the modal is closed and their selected icon appears on the card (this feature is one that allows the user to create a custom card).
I then have a feature that allows the user to change the line colour from white to black and visa versa on the card to contrast with their selected background colour. I would also like the colour of the icon to change with the lines, but I cannot find a solution! The icon object itself is read-only and using a StyleSheet seems to only apply styles when it is referenced within the original call like:
<FontAwesomeIcon icon={archive} style = {styles.text} />
I can't seem to wrap it in a styled view and then change the style from there.
Any ideas on how to alter the colour? And the size while I'm asking?
You can make state like this :
const [style,setStyle]=useState()
You change state with user color, and apply it to your FontAwesome icon
<FontAwesomeIcon icon={archive} style = {style} />
Thanks for the answers! I ended up creating a library to reference and just passed the library prefix (fab, far, fas) and the icon name (coffee, archive, wifi). Then used:
<FontAwesomeIcon icon={[icon.props.icon[0], icon.props.icon[1]]} style ={blabla} size = {blabla} />
Meaning I can now manipulate the size and colour wherever I want! Very handy.

React native slider > unable to get the position value by tapping on multiple sliders

I have designed a custom player view by using react-native-slider. There are multiple sliders arranged in this view. I am playing one audio file by following the sliders which are arranged in a FlatList component. All slider having its minimum and maximum value difference is 5 seconds.
Audio is playing as expected in each slider, but I need to tap on any of the slider position to set my current slider cursor on the same place. I am trying to get the position when click on the slider. The following methods :
onValueChange
onTouchStart
onTouchEnd
have no help to get the position/value on tap on any of the slider.
Following is the slider implementation in my code :
<Slider
key={index}
step={1}
onTouchStart={this.onSliderEditStart}
onTouchEnd={this.onSliderEditEnd}
value={sliderValue}
onValueChange={this.onSliderEditing}
maximumValue={item.endTime}
minimumValue={item.startTime}
animateTransitions
// maximumTrackTintColor='transparent'
maximumTrackTintColor={'#000'}
minimumTrackTintColor={'#d3d3d3'}
thumbStyle={{height: 55, width: 2.5}}
thumbTintColor={currentTime >= item.endTime ? 'transparent' : '#000066'}
trackStyle={{height: 55, backgroundColor: '#E6E6E6'}}
/>
Please help to find out the solution if any.

What is pointer event in React-Native

I was going through the pointer event in React-native
In the docs, they have mentioned
Controls whether the View can be the target of touch events.
• 'auto': The View can be the target of touch events.
• 'none': The View is never the target of touch events.
• 'box-none': The View is never the target of touch events but it's subviews can be. It behaves like if the view had the following classes in CSS:
Here, I am
Able to comprehend from property none that no touch events would work I.e touchableOpacity (and other touch events)? Is that correct?
But from the following tutorial video on YouTube
https://www.youtube.com/watch?v=aFwBzWV6A-w
It appears the author is using it disable events like textInput and rather using it for events like touchableOpactiy.
When setting pointerEvents to none, you are disabling all touch events for the view's children. This works for all Touchables but also for Inputs etc.
In the video, the author is using it, to prevent the TextInput from getting focused, but he keeps the TouchableOpacity enabled to fire the animation. (See below Example)
Example:
Here, I am disabling the TextInput, but I am keeping the Touchable active:
<View>
<TouchableOpacity>
<View pointerEvents="none">
<TextInput ... />
</View>
</TouchableOpacity>
</View>
If I would add pointerEvents="none" to the root View, both Touchable and TextInput would be deactivated.

React Native handle touch release

I have a component which when the user long press a card I show a bigger version of this card.
The ideia is that the bigger card will be shown as long as the user keep pressing the touch and then will hide only when the finger is released (something like instagram long press). I tried to archieve this using the onLongPress and the onPressOut props of <TouchableHighlight>, the thing is that the onPressOut props has something that they call "cancel",
/**
* Called when the touch is released,
* but not if cancelled (e.g. by a scroll that steals the responder lock).
*/
What is happening is that when the user hold and move the finger the onPressOut prop is called, therefore the bigger card is hidden.
This is the code:
<View style={styles.container}>
<View style={styles.separator}>
<TouchableHighlight
underlayColor="rgba(255, 255, 255, 0)"
onPress={this.cardClick}
onLongPress={this.cardLongPress}
onPressOut={this.cardPressOut}
>
{this.content}
</TouchableHighlight>
</View>
</View>
Here is a GIF to show what is happening:
GIF
What I want is something that is only triggered when the user acctually releases his finger, regardless of whether or not he is moving the finger arround. Thanks in advance for the help.
Try setting an offset https://facebook.github.io/react-native/docs/touchablewithoutfeedback#pressretentionoffset , or convert your root view in a touchablewithoutfeedback, and call onPressOut there
So you want an Instagram style preview modal. I got you.
As mentioned in previous comments, you should use the pressRetentionOffset prop that will let you "extend" the pressable area. https://facebook.github.io/react-native/docs/touchablewithoutfeedback#pressretentionoffset
But! this prop will only work if the ScrollView is disabled. so you will need to disable the scrolling when the preview modal is shown.
You can do that with the scrollEnabled prop on ScrollView and make it falsy when the preview modal is shown.
Of course, this works with onLongPress and onPressOut props.