feat: 适配 headerbar ios26
This commit is contained in:
@@ -3,10 +3,11 @@ import { Colors } from '@/constants/Colors';
|
||||
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
|
||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
import { useCosUpload } from '@/hooks/useCosUpload';
|
||||
import { useSafeAreaTop } from '@/hooks/useSafeAreaWithPadding';
|
||||
import { fetchMyProfile, updateUserProfile } from '@/store/userSlice';
|
||||
import { fetchMaximumHeartRate } from '@/utils/health';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import AsyncStorage from '@/utils/kvStore';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import DateTimePicker from '@react-native-community/datetimepicker';
|
||||
import { Picker } from '@react-native-picker/picker';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
@@ -21,14 +22,12 @@ import {
|
||||
Modal,
|
||||
Platform,
|
||||
Pressable,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
|
||||
@@ -47,6 +46,7 @@ interface UserProfile {
|
||||
const STORAGE_KEY = '@user_profile';
|
||||
|
||||
export default function EditProfileScreen() {
|
||||
const safeAreaTop = useSafeAreaTop()
|
||||
const colorScheme = useColorScheme();
|
||||
const colors = Colors[colorScheme ?? 'light'];
|
||||
const dispatch = useAppDispatch();
|
||||
@@ -287,10 +287,7 @@ export default function EditProfileScreen() {
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: '#F5F5F5' }]}>
|
||||
<StatusBar barStyle={'dark-content'} />
|
||||
|
||||
{/* HeaderBar 放在 ScrollView 外部,确保全宽显示 */}
|
||||
<View style={[styles.container, { backgroundColor: '#F5F5F5' }]}>
|
||||
<HeaderBar
|
||||
title="编辑资料"
|
||||
onBack={() => router.back()}
|
||||
@@ -300,7 +297,7 @@ export default function EditProfileScreen() {
|
||||
/>
|
||||
|
||||
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : undefined} style={{ flex: 1 }}>
|
||||
<ScrollView contentContainerStyle={{ paddingBottom: 40 }} style={{ paddingHorizontal: 20 }} showsVerticalScrollIndicator={false}>
|
||||
<ScrollView contentContainerStyle={{ paddingBottom: 40, paddingTop: safeAreaTop }} style={{ paddingHorizontal: 20 }} showsVerticalScrollIndicator={false}>
|
||||
|
||||
{/* 头像(带相机蒙层,点击从相册选择) */}
|
||||
<View style={{ alignItems: 'center', marginTop: 4, marginBottom: 32 }}>
|
||||
@@ -504,7 +501,7 @@ export default function EditProfileScreen() {
|
||||
</Modal>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,17 +6,17 @@ import * as Haptics from 'expo-haptics';
|
||||
import { useRouter } from 'expo-router';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
View
|
||||
} from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
import { ProgressBar } from '@/components/ProgressBar';
|
||||
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
|
||||
import { useSafeAreaTop } from '@/hooks/useSafeAreaWithPadding';
|
||||
import { updateUser as updateUserApi } from '@/services/users';
|
||||
import { fetchMyProfile } from '@/store/userSlice';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
@@ -43,6 +43,7 @@ function arraysEqualUnordered(a?: string[], b?: string[]): boolean {
|
||||
}
|
||||
|
||||
export default function GoalsScreen() {
|
||||
const safeAreaTop = useSafeAreaTop()
|
||||
const router = useRouter();
|
||||
const insets = useSafeAreaInsets();
|
||||
const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
|
||||
@@ -135,7 +136,7 @@ export default function GoalsScreen() {
|
||||
lastSentRef.current.calories = calories;
|
||||
(async () => {
|
||||
try {
|
||||
await updateUserApi({ userId, dailyCaloriesGoal: calories });
|
||||
await updateUserApi({ dailyCaloriesGoal: calories });
|
||||
await dispatch(fetchMyProfile() as any);
|
||||
} catch { }
|
||||
})();
|
||||
@@ -148,7 +149,7 @@ export default function GoalsScreen() {
|
||||
lastSentRef.current.steps = steps;
|
||||
(async () => {
|
||||
try {
|
||||
await updateUserApi({ userId, dailyStepsGoal: steps });
|
||||
await updateUserApi({ dailyStepsGoal: steps });
|
||||
await dispatch(fetchMyProfile() as any);
|
||||
} catch { }
|
||||
})();
|
||||
@@ -161,7 +162,7 @@ export default function GoalsScreen() {
|
||||
lastSentRef.current.purposes = [...purposes];
|
||||
(async () => {
|
||||
try {
|
||||
await updateUserApi({ userId, pilatesPurposes: purposes });
|
||||
await updateUserApi({ pilatesPurposes: purposes });
|
||||
await dispatch(fetchMyProfile() as any);
|
||||
} catch { }
|
||||
})();
|
||||
@@ -245,9 +246,9 @@ export default function GoalsScreen() {
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor: theme === 'light' ? '#F5F5F5' : colors.background }]}>
|
||||
<SafeAreaView style={styles.safeArea}>
|
||||
<View style={styles.safeArea}>
|
||||
<HeaderBar title="目标管理" onBack={() => router.back()} withSafeTop={false} tone={theme} transparent />
|
||||
<ScrollView contentContainerStyle={[styles.content, { paddingBottom: Math.max(20, insets.bottom + 16) }]}
|
||||
<ScrollView contentContainerStyle={[styles.content, { paddingBottom: Math.max(20, insets.bottom + 16), paddingTop: safeAreaTop }]}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<SectionCard title="每日卡路里消耗目标" subtitle="设置你计划每天通过活动消耗的热量">
|
||||
@@ -305,7 +306,7 @@ export default function GoalsScreen() {
|
||||
</SectionCard>
|
||||
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user