首页 > 解决方案 > Material UI 日期选择器在移动设备上的行为不同

问题描述

我在 React 项目中使用 Material UI 日期选择器。我创建了一个日历+时间选择(下面的代码)。出于某种原因,当我在 Chrome 桌面上使用设备工具栏模拟 iphone 8 进行测试时,它工作正常,但是当我在我的实际 iphone 8 上访问该站点时,用户界面已损坏(下图)。有什么想法吗?

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Button, Typography } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import moment from 'moment';
import { MuiPickersUtilsProvider, DatePicker } from '@material-ui/pickers';
import DateFnsUtils from '@date-io/date-fns';

const useStyles = makeStyles(theme => ({
    root: {
        display: 'flex',
        flexDirection: 'row',
        padding: theme.spacing(3),
        [theme.breakpoints.down('sm')]: {
            padding: 0,
        },
    },
    picker: {
        display: 'flex',
        flexDirection: 'row',
        [theme.breakpoints.down('sm')]: {
            flexDirection: 'column',
        },
    },
    timeContainer: {
        display: 'flex',
        flexDirection: 'column',
        marginLeft: theme.spacing(2),
        overflowY: 'scroll',
        [theme.breakpoints.down('sm')]: {
            alignItems: 'center',
            marginLeft: 0,
            marginBottom: theme.spacing(3),
        },
    },
    timeButton: { width: 226, height: 50 },
}));

export default function Timesgrid(props) {
    const classes = useStyles();

    const [selectedDate, setSeletedDate] = useState(moment());

    const disableDay = date => {
        const formattedDate = moment(date).format('YYYY-MM-DD');
        return formattedDate in props.availability &&
            props.availability[formattedDate].length > 0
            ? false
            : true;
    };

    const handleDateChange = date => {
        setSeletedDate(moment(date));
    };

    const renderTimes = () => {
        const dateStr = moment(selectedDate).format('YYYY-MM-DD');
        const availability = props.availability[dateStr];
        return availability && availability.length ? (
            <div className={classes.timeContainer}>
                {availability.map((time, i) => (
                    <Button
                        style={{ marginTop: i === 0 ? 0 : 10 }}
                        key={time}
                        className={classes.timeButton}
                        variant="outlined"
                        color="primary"
                        onClick={() => props.onDatetimeSelected(moment(time))}
                    >
                        <b>{moment(time).format('LT')}</b>
                    </Button>
                ))}
            </div>
        ) : (
            <Typography variant="h6" className={classes.timeContainer}>
                No availability
            </Typography>
        );
    };
    const renderPicker = () => {
        return (
            <div className={classes.picker}>
                <MuiPickersUtilsProvider utils={DateFnsUtils}>
                    <DatePicker
                        disablePast
                        shouldDisableDate={disableDay}
                        variant="static"
                        defaultValue={selectedDate}
                        value={selectedDate}
                        onChange={handleDateChange}
                    />
                </MuiPickersUtilsProvider>
                {renderTimes()}
            </div>
        );
    };

    return <div className={classes.root}>{renderPicker()}</div>;
}

Timesgrid.propTypes = {
    availability: PropTypes.object.isRequired,
    onDatetimeSelected: PropTypes.func.isRequired,
};

在 Chrome iphone8 模拟器上

在我的 iphone8 上

标签: reactjsmaterial-ui

解决方案


正如我们在评论中讨论的那样,您的问题的答案是添加以下 CSS 样式。

overflow: scroll
height: 100%

理由:

我建议此解决方案的原因是由于您的图像中的比较。该组件的弹出屏幕在本机浏览器弹出窗口中混合在一起,但不是在 Chrome DevTools 弹出窗口中。这表明本机浏览器容器不允许发生溢出。

将组件的高度设置为 100% 可确保它占据其容器的整个高度,并允许溢出确保如果您的组件大于容器高度的 100%,它将如 devtools 视图中所示呈现。

此外,在您的回复中,您说您的解决方案是

overflowY: scroll, 
height: 100%

和溢出:滚动允许在两个轴上溢出。由于 x 轴不需要溢出,这是一个更好的解决方案。

很高兴看到它奏效了。


推荐阅读