Files
hipmi-mobile/TASKS/fix-phone-input-ios-16.md
bagasbanuna 2e58f8c7b4 Docs: add task breakdown untuk fix phone input iOS 16+
- Add TASKS/fix-phone-input-ios-16.md dengan analisis lengkap
- 3 opsi solusi: KeyboardAvoidingView, Keyboard Controller, Custom Input
- Detailed implementation guidelines
- Testing checklist untuk iOS 16, 17, 18

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-25 16:39:48 +08:00

9.8 KiB

Fix Phone Number Input - iOS 16+ Compatibility

📋 Ringkasan Task

Memperbaiki masalah phone number input pada screens/Authentication/LoginView.tsx yang tidak berfungsi dengan baik pada iOS versi 16 ke atas.


🎯 Tujuan

  1. Fix keyboard overlay issues pada iOS 16+
  2. Perbaiki layout measurement dan safe area
  3. Pastikan input phone number responsive di semua device
  4. Maintain UX yang konsisten dengan Android

📁 File yang Terlibat

File Utama

  • Target: screens/Authentication/LoginView.tsx

File Pendukung

  • components/TextInput/TextInputCustom.tsx - Alternatif custom input
  • styles/global-styles.ts - Styling adjustments
  • package.json - Update dependencies (jika perlu)

Dependencies Terkait

  • react-native-international-phone-number: ^0.9.3
  • react-native-keyboard-controller: ^1.18.6

🔍 Analisis Masalah

Issues pada iOS 16+

1. Keyboard Overlay Problem

Symptom: Input field tertutup keyboard saat aktif Cause:

  • Safe area insets tidak terhitung dengan benar
  • Keyboard animation tidak sinkron dengan layout
  • react-native-keyboard-controller tidak terintegrasi dengan baik

2. Layout Measurement Issues

Symptom: Input field berubah ukuran secara tidak terduga Cause:

  • Dynamic Type settings mempengaruhi layout
  • Font scaling pada iOS 16+ berbeda
  • Container tidak memiliki fixed height

3. Focus Behavior

Symptom: Input tidak auto-scroll saat di-focus Cause:

  • ScrollView/KeyboardAvoidingView configuration salah
  • Keyboard dismissing behavior tidak konsisten

4. Visual Glitches

Symptom: Country flag dropdown tidak muncul atau terpotong Cause:

  • Z-index issues pada iOS
  • Modal/Popover rendering problems

🎨 Solusi yang Direkomendasikan

Effort: Medium Impact: High

import { KeyboardAvoidingView, Platform } from "react-native";

<KeyboardAvoidingView
  behavior={Platform.OS === "ios" ? "padding" : "height"}
  keyboardVerticalOffset={Platform.OS === "ios" ? 90 : 50}
  style={{ flex: 1 }}
>
  <ViewWrapper>
    {/* Content */}
  </ViewWrapper>
</KeyboardAvoidingView>

Keuntungan:

  • Native solution dari React Native
  • Tidak perlu tambahan library
  • Stabil untuk iOS 16+

Kekurangan:

  • Perlu tuning offset untuk setiap device
  • Tidak se-smooth keyboard controller

Option 2: React Native Keyboard Controller (BETTER UX)

Effort: Medium-High Impact: High

import { KeyboardProvider } from "react-native-keyboard-controller";

// Wrap di root app (sudah ada di _layout.tsx)
<KeyboardProvider>
  <App />
</KeyboardProvider>

// Di LoginView
import { KeyboardAwareScrollView } from "react-native-keyboard-controller";

<KeyboardAwareScrollView
  bottomOffset={20}
  keyboardOffset={10}
>
  {/* Content */}
</KeyboardAwareScrollView>

Keuntungan:

  • Smooth keyboard animations
  • Better control over keyboard behavior
  • Cross-platform consistency

Kekurangan:

  • Perlu verify konfigurasi yang sudah ada
  • Mungkin perlu update library

Option 3: Custom Phone Input (FALLBACK)

Effort: High Impact: Medium

Membuat custom phone input dengan:

  • TextInputCustom component
  • Country code picker modal
  • Validation logic

Keuntungan:

  • Full control atas behavior
  • Tidak depend on third-party issues

Kekurangan:

  • Development time lebih lama
  • Perlu testing ekstensif
  • Maintain code sendiri

📝 Breakdown Task

Task 1: Research & Setup

  • Identifikasi masalah pada iOS 16+
  • Cek dokumentasi library
  • Review existing implementation
  • Test di iOS simulator (iOS 16+)
  • Test di device fisik (jika ada)

Task 2: Implement KeyboardAvoidingView Fix

  • Wrap ViewWrapper dengan KeyboardAvoidingView
  • Set behavior berdasarkan Platform
  • Adjust keyboardVerticalOffset
  • Test di berbagai ukuran layar
  • Test landscape mode (jika applicable)

Task 3: Adjust Layout & Styling

  • Fix container height/width
  • Adjust safe area insets
  • Test dengan Dynamic Type settings
  • Ensure consistent padding/margin

Task 4: Test Focus Behavior

  • Auto-scroll saat focus
  • Keyboard dismiss saat tap outside
  • Next/previous field navigation (jika ada)
  • Input validation on blur

Task 5: Country Picker Fix

  • Verify dropdown z-index
  • Test modal presentation
  • Ensure flag icons visible
  • Test search functionality

Task 6: Testing & QA

  • Test iOS 16, 17, 18
  • Test Android (regression)
  • Test dengan berbagai device sizes
  • Test accessibility (VoiceOver)
  • Performance test (no lag)

Task 7: Documentation

  • Update code comments
  • Document iOS-specific workarounds
  • Add troubleshooting notes

💻 Implementation Guidelines

import { KeyboardAvoidingView, Platform } from "react-native";
import { KeyboardProvider } from "react-native-keyboard-controller";

// Di LoginView.tsx
export default function LoginView() {
  return (
    <ViewWrapper
      withBackground
      refreshControl={
        <RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />
      }
    >
      <KeyboardAvoidingView
        behavior={Platform.OS === "ios" ? "padding" : "height"}
        keyboardVerticalOffset={Platform.OS === "ios" ? 100 : 50}
        style={{ flex: 1 }}
      >
        <View style={[GStyles.authContainer, { paddingBottom: 40 }]}>
          {/* Title Section */}
          <View style={GStyles.authContainerTitle}>
            <Text style={GStyles.authSubTitle}>WELCOME TO</Text>
            <Spacing height={5} />
            <Text style={GStyles.authTitle}>HIPMI BADUNG APPS</Text>
            <Spacing height={5} />
          </View>
          
          <Spacing height={50} />
          
          {/* Phone Input - Wrap dengan View untuk stability */}
          <View style={{ marginBottom: 20 }}>
            <PhoneInput
              value={inputValue}
              onChangePhoneNumber={handleInputValue}
              selectedCountry={selectedCountry}
              onChangeSelectedCountry={handleSelectedCountry}
              defaultCountry="ID"
              placeholder="Masukkan nomor"
              // Add iOS-specific props
              textInputProps={{
                keyboardType: "phone-pad",
                autoComplete: "tel",
                importantForAutofill: "yes",
              }}
            />
          </View>
          
          <Spacing />
          
          {/* Login Button */}
          <ButtonCustom
            onPress={handleLogin}
            disabled={loadingTerm}
            isLoading={loading || loadingTerm}
          >
            Login
          </ButtonCustom>
          
          <Spacing height={50} />
          
          {/* Terms Text */}
          <Text style={{ ...GStyles.textLabel, textAlign: "center", fontSize: 12 }}>
            Dengan menggunakan aplikasi ini, Anda telah menyetujui{" "}
            <Text
              style={{
                color: MainColor.yellow,
                textDecorationLine: "underline",
              }}
              onPress={() => {
                const toUrl = `${url}/terms-of-service.html`;
                openBrowser(toUrl);
              }}
            >
              Syarat & Ketentuan
            </Text>{" "}
            dan seluruh kebijakan privasi yang berlaku.
          </Text>
          
          {/* Version Info */}
          <Text
            style={{
              position: "absolute",
              bottom: 35,
              right: 50,
              fontSize: 10,
              fontWeight: "thin",
              fontStyle: "italic",
              color: MainColor.white_gray,
            }}
          >
            {version} | powered by muku.id
          </Text>
        </View>
      </KeyboardAvoidingView>
    </ViewWrapper>
  );
}

Styling Adjustments

// styles/global-styles.ts
export const GStyles = StyleSheet.create({
  authContainer: {
    flex: 1,
    justifyContent: "center",
    paddingHorizontal: 24,
    // Add padding bottom untuk keyboard space
    paddingBottom: Platform.OS === "ios" ? 40 : 20,
  },
  // ... existing styles
});

Acceptance Criteria

Functional

  • Input field tidak tertutup keyboard saat focus
  • Country picker dropdown berfungsi dengan baik
  • Auto-scroll bekerja smooth saat focus
  • Keyboard dismiss saat tap outside
  • Input validation berjalan normal

Visual

  • Layout tidak berubah saat keyboard muncul
  • No visual glitches atau flickering
  • Country flag icons visible
  • Consistent spacing dan padding

Compatibility

  • iOS 16, 17, 18 - Tested
  • Android - No regression
  • iPad - Responsive
  • Landscape mode - Usable

Performance

  • No lag saat typing
  • Smooth keyboard animations
  • No memory leaks
  • Fast input response

🔗 References


📊 Estimated Effort

  • Complexity: Medium
  • Time Estimate: 2-4 jam
  • Risk Level: Medium (perlu testing ekstensif di device)

📝 Notes

  • Priority: High (login adalah critical path)
  • Testing: Wajib test di device fisik jika memungkinkan
  • Fallback: Jika Option 1 & 2 gagal, siap untuk implement Option 3 (custom input)
  • Monitoring: Add analytics untuk track input completion rate

Created: 2026-03-25 Status: Pending Priority: High Related Issue: iOS 16+ keyboard compatibility