【问题标题】:React Native, iOS - ScrollView doesn't work on deviceReact Native,iOS - ScrollView 在设备上不起作用
【发布时间】:2017-02-18 22:10:53
【问题描述】:

ScrollView 在 iOS 模拟器上工作,但在设备上的 Exponent 上实际运行时它不起作用。触摸释放后返回顶部。我不确定这是我的代码的问题还是 React Native 或 Exponent 方面的错误。以下是我的环境的详细信息:

React Native 版本:0.41

指数版本:14

指向指数应用程序的链接:

https://exp.host/@prez/hairapp

在 iOS 模拟器上工作的 ScrollView 演示:

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,您会发现它工作得很好,因为现在容器知道他们孩子的身高,因此滚动视图也知道。我的建议是用滚动视图替换你的容器视图,而不是在滚动视图中调用你的长日历。这是你的日历需要滚动,不是吗?让我知道这是否有帮助,所以我可以格式化我的答案
  • 嗨 Enie,我按照您的建议从容器样式中删除了 flex: 1,但这仍然无法在 Exponent 上的设备上运行。我后来检查的。我已经将此案例重写为没有 Exponent 的纯 React Native 项目,并将其运行到没有 Exponent 应用程序的真实设备上,并且......它工作得很好......所以它看起来可能是一些 Exponent 错误。我将根据您关于 flex 和 height 的建议重构我的代码,但它仍然无法回答为什么它适用于 RN 项目以及为什么它不适用于 Exponent 项目。
  • 是的,我同意,你最好在 react native facebook group 中参考这篇文章,专家们可能会修复这个错误。

标签: ios reactjs react-native exponentjs


【解决方案1】:

在设备上重新安装 Exponent 后它可以工作。重装前后版本相同。

【讨论】:

  • 我发现它与指数无关;任何类型的库都可能发生这种情况。但对我来说,解决方法是完全删除该应用程序,然后在下次安装时它可以正常工作。
猜你喜欢
  • 1970-01-01
  • 2020-03-25
  • 2018-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 2021-08-12
相关资源
最近更新 更多