feat: 适配 headerbar ios26

This commit is contained in:
richarjiang
2025-10-14 16:31:19 +08:00
parent cf069f3537
commit 435f5cc65c
41 changed files with 493 additions and 5445 deletions

View File

@@ -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>
);
}

View File

@@ -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>
);
}