ScrollView在iOS模擬器上工作,但它實際上在設備上的Exponent上運行時不起作用。它在觸摸釋放後回到頂端。我不確定這是否是我的代碼的問題,或者它是React Native或Exponent方面的錯誤。下面是我的環境的詳細信息:React Native,iOS - ScrollView在設備上不起作用
陣營原生版本:0.41
指數版本:14
鏈接到指數應用:
https://exp.host/@prez/hairapp
在iOS模擬器工作的滾動型的演示:
https://www.youtube.com/watch?v=3VH-6a-sMok
個main.js
import Exponent from 'exponent';
import React from 'react';
import {AppRegistry, Text, Button, View, ScrollView} from 'react-native';
import {StackNavigator} from 'react-navigation';
import Calendar from './modules/calendar';
class CalendarView extends React.Component {
static navigationOptions = {
title: 'Calendar'
}
render() {
return (
<ScrollView>
<Calendar/>
</ScrollView>
)
}
}
const SimpleApp = StackNavigator({
Home: {
screen: CalendarView
}
});
Exponent.registerRootComponent(SimpleApp);
./modules/calendar/index.js
import React, {Component} from 'react';
import {Text, View, StyleSheet} from 'react-native';
import moment from 'moment';
export default class Calendar extends Component {
state = {
reservations: [
{
hour: '2017-02-17 00:00',
duration: 120
}, {
hour: '2017-02-17 02:00',
duration: 60
}, {
hour: '2017-02-17 03:00',
duration: 120
}, {
hour: '2017-02-17 05:00',
duration: 180
}, {
hour: '2017-02-17 08:00',
duration: 120
}
]
}
generateIntervalHours() {
let hours = [];
// interval has been imported from database configuration, set in minutes
const interval = 60;
// current set day, date set only for test purposes
let it = moment('2017-02-17').hours(0).minutes(0);
const itEnd = moment(it).hours(23).minutes(59);
while (it < itEnd) {
hours.push(moment(it));
it.add(interval, 'minutes');
}
return hours;
}
// Function to display hours next to lines/events. Displaying hours and events must be
// seperated because the line starts in the middle of the hour text and ends in the
// middle of the next hours text so it would be not possible to display hour and event/line
// as a single row. Former event block would have to overlay next block to reach middle of the text.
displayHours =() => (this.generateIntervalHours().map(item => (
<View key={item.format('HH:mm')} style={styles.hours}>
<Text style={{
color: 'rgb(107, 108, 109)',
fontSize: 12
}}>{item.format('HH:mm')}</Text>
</View>
)))
// Function to display lines/events next to hours
displayTimetable =() => (this.generateIntervalHours().map(hour => {
const {reservations} = this.state;
// test current hour if there is reservation
// that start or lasts during this hour
const slot = reservations.find(res => {
const startH = moment(res.hour, 'YYYY-MM-DD HH:mm');
const endH = moment(startH).add(res.duration, 'minutes');
return (hour >= startH && hour < endH);
});
// no reservation starting with the hour tested
// no reservation that lasts during the hour tested
// View with upper border line will be displayed
// what says that nothing is scheduled for this hour
if (typeof slot == 'undefined') {
return (<View key={hour.format('HH:mm')} style={[
styles.timetable, {
height: 60
}
]}/>);
// reservation found that lasts during the tested hour
// nothing to display
} else if (hour.format('YYYY-MM-DD HH:mm') != slot.hour) {
return null;
// reservation found with starting hour as tested hour
// View with height set to duration will be displayed
} else {
return <View key={hour.format('HH:mm')} style={[
styles.timetable, {
height: slot.duration,
backgroundColor: 'rgb(32, 127, 227)'
}
]}/>
};
}))
render() {
return (
<View style={styles.container}>
<View>
{this.displayHours()}
</View>
<View style={styles.timetablePadding}>
{this.displayTimetable()}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginLeft: 10,
marginTop: 10,
marginRight: 10,
flexDirection: 'row'
},
timetablePadding: {
flex: 1,
paddingTop: 10
},
hours: {
marginBottom: 40,
// borderWidth: 1,
// borderRadius: 2,
// borderColor: '#ddd',
marginRight: 10,
height: 20,
width: 50,
justifyContent: 'center'
},
timetable: {
flexDirection: 'row',
//borderWidth: 1,
borderRadius: 2,
//borderColor: '#ddd',
borderTopColor: 'rgb(238, 239, 240)',
borderTopWidth: 1,
borderBottomWidth: 1,
borderBottomColor: 'white'
},
line: {
flex: 1,
height: 1,
backgroundColor: 'black'
}
});
嘿Przemek,我認爲你不應該用'flex:1'來設計你的日曆容器,因爲scrollview的唯一子對象將是一個伸展到所有可用空間的巨大視圖。但是,如果您刪除容器中的「flex:1」,就會發現它工作得很好,因爲現在容器知道他們的子女身高,因此scrollview也是如此。我的建議是用scrollview替換你的容器視圖,而不是在scrollview中調用你的長日曆。這是你的日曆需要滾動,不是嗎? 讓我知道如果這有幫助,所以我可以格式化我的答案 – eden
嗨Enie,我從容器風格刪除flex:1,如你所建議的,但這仍然無法在Exponent上的設備上工作。 我以後檢查過。我已經將這種情況改寫爲沒有指數的純React Native項目,並將其運行到沒有Exponent應用程序的真實設備,並且它工作得很好......所以它似乎是一些Exponent bug。 我會重構我的代碼給你關於flex和高度的建議,但它仍然沒有回答爲什麼它在RN項目上工作,以及它爲什麼不能在Exponent項目上工作。 –
是的,我同意,你最好在反應原生facebook組中引用這篇文章,指數人可以修復這個bug。 – eden