React Native ios 选择器始终打开
React Native ios picker is always open
我的屏幕上有两个选择器。每当我导航到 iOS 应用程序中的屏幕时,我发现选择器始终打开并且所有选项都可见。
它在 Android 中工作得很好,只有在我们点击选择器后选项才可见。
有人可以在 iOS 中提出解决此问题的解决方案吗?
这就是 iOS UIPickerView
组件的工作方式 - 无法对其进行自定义。
如果您想要不同类型的 UI 元素,您需要自己编写,或使用众多开源库之一,例如:
通过谷歌搜索这些以及类似的关键字,还可以找到许多其他库。
在 iOS 上使用 ActionSheet 而不是 Picker。
https://facebook.github.io/react-native/docs/actionsheetios
正如 jevakallio 所回答的那样,这是 iOS 上的默认行为。但这并不能提供良好的用户体验,因此删除所有选择器组件并替换为 ActionSheet。
我做了,效果很好。之所以我更喜欢 ActionSheet 而不是 jevakallio 推荐的其他组件,是因为它是由 RN 团队开发的,具有良好的原生感觉。最后一个选项建议react-native-modal-picker也很好
React-native-modal-picker 已停产。
react-native-modal-selector
我不知道您为什么会选择带有 ActionSheet 的答案作为已接受的答案。
但是我会给出解决这个问题的方法:
将这些值放入您所在的州:
this.state= {
pickerOpacity: 0,
opacityOfOtherItems: 1 //THIS IS THE OPACITY OF ALL OTHER ITEMS, WHICH COLLIDES WITH YOUR PICKER.
label: 'Firstvalue'
}
在您的渲染方法中执行以下操作:
{this.checkIfIOS()}
<Picker
selectedValue={this.state.selected}
style={{ height: 50, alignSelf: 'center', opacity: this.state.pickerOpacity, marginBottom:30, width: 250}}
onValueChange={(itemValue, itemIndex) =>{
this.setState({
selected: itemValue,
label: itemValue
});
toggle();
}
}>
<Picker.Item label="Your Label" value="yourValue"/>
</Picker>
所以现在我们要检查我们的客户是 android 还是 ios。因此,导入 Platform 并将 checkIfIos()-Method 放入您的代码中:
import {Platform} from 'react-native'
checkIfIOS(){
if(Platform.OS === 'ios'){ // check if ios
console.log("IOS!!!");
//this button will (onpress) set our picker visible
return (<Button buttonStyle={{backgroundColor:'#D1D1D1', opacity: this.state.opacityOfOtherItems}} onPress={this.toggle()} color="#101010" title={this.state.label} onPress={this.changeOpacity}/>);
}else if(Platform.OS === 'android'){ //check if android
this.setState({
pickerOpacity: 1 //set picker opacity:1 -> picker is visible.
});
console.log("ANDROID!!!");
}
}
toggle(){
if(Platform.OS === 'ios'){
if(this.state.pickerOpacity == 0){
this.setState({
pickerOpacity: 1,
opacityOfOtherItems: 0 // THIS WILL HIDE YOUR BUTTON!
});
}else{
this.setState({
pickerOpacity: 0,
opacityOfOtherItems: 1
});
}
}
}
编辑: 屏幕截图 iOS (Click here for Video)
扩展 ActionSheetIOS
答案,我创建了一个自定义组件,它是 Picker
的直接替代品(我使用 https://react-native-elements.github.io/react-native-elements/docs/overview.html 中的 Button
):
import React from 'react';
import { ActionSheetIOS, Platform } from 'react-native';
import { Button } from 'react-native-elements';
class PickerDropDown extends React.Component {
onIOSButton = () => {
let options = this.props.children.map((item, i) => {
return item.props.label;
});
options.push("Cancel");
ActionSheetIOS.showActionSheetWithOptions(
{
options: options,
cancelButtonIndex: options.length - 1,
},
this.onIOSButtonPick
);
}
onIOSButtonPick = (buttonIndex) => {
if (buttonIndex < this.props.children.length && buttonIndex != this.props.selectedValue) {
if (typeof this.props.selectedValue === 'undefined' || (typeof this.props.selectedValue !== 'undefined' && buttonIndex != this.findIndexForValue(this.props.selectedValue))) {
this.props.onValueChange(this.props.children[buttonIndex].props.value, buttonIndex);
}
}
}
findLabelForValue = (searchValue) => {
for (let i = 0; i < this.props.children.length; i++) {
if (this.props.children[i].props.value == searchValue) {
return this.props.children[i].props.label;
}
}
return null;
}
findIndexForValue = (searchValue) => {
for (let i = 0; i < this.props.children.length; i++) {
if (this.props.children[i].props.value == searchValue) {
return i;
}
}
return -1;
}
render() {
if (Platform.OS === "ios") {
let title = "";
if (this.props.children && this.props.children.length > 0) {
if (typeof this.props.selectedValue !== 'undefined') {
title = this.findLabelForValue(this.props.selectedValue);
} else {
title = this.props.children[0].props.label;
}
}
return (
<View>
<Button
title={title}
onPress={this.onIOSButton}
type="clear"
icon={{
name: "arrow-drop-down",
size: 15,
color: "black"
}}
iconRight={true}
/>
</View>
);
} else {
return (
<Picker {...this.props} />
);
}
}
}
从 native-base
库而不是 react-native
导入
react-native-dropdown 有引用错误
如果您不想使用 Action Sheets 而想使用 'real' 选择器,我发现这个更好...
使用
<Picker itemStyle={{height:50}} > </Picker>
它只影响 ios 选择器。将选择器项目样式高度更改为您的标准。
我的屏幕上有两个选择器。每当我导航到 iOS 应用程序中的屏幕时,我发现选择器始终打开并且所有选项都可见。
它在 Android 中工作得很好,只有在我们点击选择器后选项才可见。
有人可以在 iOS 中提出解决此问题的解决方案吗?
这就是 iOS UIPickerView
组件的工作方式 - 无法对其进行自定义。
如果您想要不同类型的 UI 元素,您需要自己编写,或使用众多开源库之一,例如:
通过谷歌搜索这些以及类似的关键字,还可以找到许多其他库。
在 iOS 上使用 ActionSheet 而不是 Picker。 https://facebook.github.io/react-native/docs/actionsheetios
正如 jevakallio 所回答的那样,这是 iOS 上的默认行为。但这并不能提供良好的用户体验,因此删除所有选择器组件并替换为 ActionSheet。
我做了,效果很好。之所以我更喜欢 ActionSheet 而不是 jevakallio 推荐的其他组件,是因为它是由 RN 团队开发的,具有良好的原生感觉。最后一个选项建议react-native-modal-picker也很好
React-native-modal-picker 已停产。 react-native-modal-selector
我不知道您为什么会选择带有 ActionSheet 的答案作为已接受的答案。 但是我会给出解决这个问题的方法:
将这些值放入您所在的州:
this.state= {
pickerOpacity: 0,
opacityOfOtherItems: 1 //THIS IS THE OPACITY OF ALL OTHER ITEMS, WHICH COLLIDES WITH YOUR PICKER.
label: 'Firstvalue'
}
在您的渲染方法中执行以下操作:
{this.checkIfIOS()}
<Picker
selectedValue={this.state.selected}
style={{ height: 50, alignSelf: 'center', opacity: this.state.pickerOpacity, marginBottom:30, width: 250}}
onValueChange={(itemValue, itemIndex) =>{
this.setState({
selected: itemValue,
label: itemValue
});
toggle();
}
}>
<Picker.Item label="Your Label" value="yourValue"/>
</Picker>
所以现在我们要检查我们的客户是 android 还是 ios。因此,导入 Platform 并将 checkIfIos()-Method 放入您的代码中:
import {Platform} from 'react-native'
checkIfIOS(){
if(Platform.OS === 'ios'){ // check if ios
console.log("IOS!!!");
//this button will (onpress) set our picker visible
return (<Button buttonStyle={{backgroundColor:'#D1D1D1', opacity: this.state.opacityOfOtherItems}} onPress={this.toggle()} color="#101010" title={this.state.label} onPress={this.changeOpacity}/>);
}else if(Platform.OS === 'android'){ //check if android
this.setState({
pickerOpacity: 1 //set picker opacity:1 -> picker is visible.
});
console.log("ANDROID!!!");
}
}
toggle(){
if(Platform.OS === 'ios'){
if(this.state.pickerOpacity == 0){
this.setState({
pickerOpacity: 1,
opacityOfOtherItems: 0 // THIS WILL HIDE YOUR BUTTON!
});
}else{
this.setState({
pickerOpacity: 0,
opacityOfOtherItems: 1
});
}
}
}
编辑: 屏幕截图 iOS (Click here for Video)
扩展 ActionSheetIOS
答案,我创建了一个自定义组件,它是 Picker
的直接替代品(我使用 https://react-native-elements.github.io/react-native-elements/docs/overview.html 中的 Button
):
import React from 'react';
import { ActionSheetIOS, Platform } from 'react-native';
import { Button } from 'react-native-elements';
class PickerDropDown extends React.Component {
onIOSButton = () => {
let options = this.props.children.map((item, i) => {
return item.props.label;
});
options.push("Cancel");
ActionSheetIOS.showActionSheetWithOptions(
{
options: options,
cancelButtonIndex: options.length - 1,
},
this.onIOSButtonPick
);
}
onIOSButtonPick = (buttonIndex) => {
if (buttonIndex < this.props.children.length && buttonIndex != this.props.selectedValue) {
if (typeof this.props.selectedValue === 'undefined' || (typeof this.props.selectedValue !== 'undefined' && buttonIndex != this.findIndexForValue(this.props.selectedValue))) {
this.props.onValueChange(this.props.children[buttonIndex].props.value, buttonIndex);
}
}
}
findLabelForValue = (searchValue) => {
for (let i = 0; i < this.props.children.length; i++) {
if (this.props.children[i].props.value == searchValue) {
return this.props.children[i].props.label;
}
}
return null;
}
findIndexForValue = (searchValue) => {
for (let i = 0; i < this.props.children.length; i++) {
if (this.props.children[i].props.value == searchValue) {
return i;
}
}
return -1;
}
render() {
if (Platform.OS === "ios") {
let title = "";
if (this.props.children && this.props.children.length > 0) {
if (typeof this.props.selectedValue !== 'undefined') {
title = this.findLabelForValue(this.props.selectedValue);
} else {
title = this.props.children[0].props.label;
}
}
return (
<View>
<Button
title={title}
onPress={this.onIOSButton}
type="clear"
icon={{
name: "arrow-drop-down",
size: 15,
color: "black"
}}
iconRight={true}
/>
</View>
);
} else {
return (
<Picker {...this.props} />
);
}
}
}
从 native-base
库而不是 react-native
react-native-dropdown 有引用错误 如果您不想使用 Action Sheets 而想使用 'real' 选择器,我发现这个更好...
使用
<Picker itemStyle={{height:50}} > </Picker>
它只影响 ios 选择器。将选择器项目样式高度更改为您的标准。