Ipad适配问题
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { View, StyleSheet, TextInput, Platform, Animated, TouchableOpacity, Text, Keyboard, Pressable } from 'react-native';
|
||||
import { View, StyleSheet, TextInput, Platform, Animated, TouchableOpacity, Text, Keyboard, Pressable, useWindowDimensions } from 'react-native';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { OnboardingColors } from '@/constants/OnboardingTheme';
|
||||
@@ -16,10 +16,13 @@ interface NameInputStepProps {
|
||||
export function NameInputStep({ value, onChangeText, onNext }: NameInputStepProps) {
|
||||
const { t } = useTranslation();
|
||||
const insets = useSafeAreaInsets();
|
||||
const { width, height } = useWindowDimensions();
|
||||
const isTablet = Platform.OS === 'ios' && Math.min(width, height) >= 768;
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
||||
const blinkAnim = useRef(new Animated.Value(1)).current;
|
||||
const hasInput = value.trim().length > 0;
|
||||
const inputCardWidth = isTablet ? Math.min(520, Math.floor(width * 0.72)) : 335;
|
||||
|
||||
useEffect(() => {
|
||||
const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
|
||||
@@ -62,7 +65,7 @@ export function NameInputStep({ value, onChangeText, onNext }: NameInputStepProp
|
||||
|
||||
return (
|
||||
<Pressable style={styles.container} onPress={Keyboard.dismiss} accessible={false}>
|
||||
<View style={styles.inputCard}>
|
||||
<View style={[styles.inputCard, { width: inputCardWidth }]}>
|
||||
<View style={styles.inputWrapper}>
|
||||
{/* 显示层:文案 + 跟随的光标 */}
|
||||
<View style={styles.displayLayer}>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import { View, StyleSheet, SafeAreaView, TouchableOpacity, StatusBar, Text, Image, Platform, Animated, Easing } from 'react-native';
|
||||
import { View, StyleSheet, SafeAreaView, TouchableOpacity, StatusBar, Text, Image, Platform, Animated, Easing, useWindowDimensions } from 'react-native';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { OnboardingColors, OnboardingFont } from '@/constants/OnboardingTheme';
|
||||
|
||||
@@ -29,6 +29,9 @@ export function OnboardingLayout({
|
||||
userName = '',
|
||||
}: OnboardingLayoutProps) {
|
||||
const { t } = useTranslation();
|
||||
const { width, height } = useWindowDimensions();
|
||||
const isTablet = Platform.OS === 'ios' && Math.min(width, height) >= 768;
|
||||
const contentMaxWidth = isTablet ? 620 : undefined;
|
||||
const showGreeting = currentStep === 1 && userName.trim().length > 0;
|
||||
const displayName = userName.trim();
|
||||
const prevStepRef = useRef(currentStep);
|
||||
@@ -72,7 +75,7 @@ export function OnboardingLayout({
|
||||
<StatusBar barStyle="dark-content" />
|
||||
<SafeAreaView style={styles.safeArea}>
|
||||
{/* Header: Back & Skip */}
|
||||
<View style={styles.header}>
|
||||
<View style={[styles.header, contentMaxWidth ? { maxWidth: contentMaxWidth, width: '100%', alignSelf: 'center' } : null]}>
|
||||
<View style={styles.headerLeft}>
|
||||
{showBackButton && onBack && (
|
||||
<TouchableOpacity onPress={onBack} style={styles.iconButton}>
|
||||
@@ -94,7 +97,7 @@ export function OnboardingLayout({
|
||||
</View>
|
||||
|
||||
{/* Title & Progress Row(名字步骤后第一步且名字非空时显示招呼语 + 问题) */}
|
||||
<View style={styles.titleRow}>
|
||||
<View style={[styles.titleRow, contentMaxWidth ? { maxWidth: contentMaxWidth, width: '100%', alignSelf: 'center' } : null]}>
|
||||
<View style={styles.titleBlock}>
|
||||
{showGreeting && (
|
||||
<Text style={styles.greetingText}>{t('onboardingSurvey.greeting', { name: displayName })}</Text>
|
||||
@@ -108,6 +111,7 @@ export function OnboardingLayout({
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.content,
|
||||
contentMaxWidth ? { maxWidth: contentMaxWidth, width: '100%', alignSelf: 'center' } : null,
|
||||
{
|
||||
opacity,
|
||||
transform: [{ translateX }],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet, TouchableOpacity, Text, Platform, ActivityIndicator } from 'react-native';
|
||||
import { View, StyleSheet, TouchableOpacity, Text, Platform, ActivityIndicator, useWindowDimensions } from 'react-native';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
@@ -20,6 +20,9 @@ interface ReminderStepProps {
|
||||
export function ReminderStep({ value, onChange, onFinish, loading = false }: ReminderStepProps) {
|
||||
const { t } = useTranslation();
|
||||
const insets = useSafeAreaInsets();
|
||||
const { width, height } = useWindowDimensions();
|
||||
const isTablet = Platform.OS === 'ios' && Math.min(width, height) >= 768;
|
||||
const contentMaxWidth = isTablet ? 560 : undefined;
|
||||
|
||||
const handleReduce = () => {
|
||||
// 本页最小为 1;不接收提醒请使用右上角 Skip
|
||||
@@ -32,7 +35,7 @@ export function ReminderStep({ value, onChange, onFinish, loading = false }: Rem
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.counterContainer}>
|
||||
<View style={[styles.counterContainer, contentMaxWidth ? { maxWidth: contentMaxWidth } : null]}>
|
||||
<TouchableOpacity onPress={handleReduce} disabled={loading} activeOpacity={0.7}>
|
||||
<ReduceIcon width={47} height={47} />
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet, TouchableOpacity, ScrollView, Text } from 'react-native';
|
||||
import { View, StyleSheet, TouchableOpacity, ScrollView, Text, Platform, useWindowDimensions } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { OnboardingColors, OnboardingFont } from '@/constants/OnboardingTheme';
|
||||
import BtnNotClicked from '@/assets/images/icon/btn_Notclicked.svg';
|
||||
@@ -19,9 +19,12 @@ interface SelectionStepProps {
|
||||
}
|
||||
|
||||
export function SelectionStep({ options, selectedIds, onToggle, onNext, onSkip }: SelectionStepProps) {
|
||||
const { width, height } = useWindowDimensions();
|
||||
const isTablet = Platform.OS === 'ios' && Math.min(width, height) >= 768;
|
||||
const maxOptionWidth = isTablet ? 560 : undefined;
|
||||
const hasSelection = selectedIds.length > 0;
|
||||
const insets = useSafeAreaInsets();
|
||||
const footerBottom = insets.bottom + 16;
|
||||
const footerBottom = insets.bottom + (isTablet ? 38 : 28);
|
||||
const footerButtonHeight = 57;
|
||||
// 底部留白加大,避免最后一项与按钮边框视觉重叠
|
||||
const footerPaddingBottom = footerBottom + footerButtonHeight + 40;
|
||||
@@ -31,14 +34,24 @@ export function SelectionStep({ options, selectedIds, onToggle, onNext, onSkip }
|
||||
<ScrollView
|
||||
style={styles.scroll}
|
||||
showsVerticalScrollIndicator={false}
|
||||
contentContainerStyle={[styles.optionsList, { paddingBottom: footerPaddingBottom }]}
|
||||
contentContainerStyle={[
|
||||
styles.optionsList,
|
||||
{
|
||||
paddingBottom: footerPaddingBottom,
|
||||
alignItems: 'center',
|
||||
},
|
||||
]}
|
||||
>
|
||||
{options.map((option) => {
|
||||
const isSelected = selectedIds.includes(option.id);
|
||||
return (
|
||||
<TouchableOpacity
|
||||
key={option.id}
|
||||
style={[styles.optionCard, isSelected && styles.optionCardSelected]}
|
||||
style={[
|
||||
styles.optionCard,
|
||||
maxOptionWidth ? { maxWidth: maxOptionWidth } : null,
|
||||
isSelected && styles.optionCardSelected,
|
||||
]}
|
||||
onPress={() => onToggle(option.id)}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user