페이지 뷰 WebView

페이지 뷰 WebView

지난 시간에 페이지 UI가 어디에 위치하는지 배웠습니다. 이번 시간에는 이어서 학습하겠습니다.

단일 네이티브 웹 뷰(WebView) 이해하기

NativePHP로 제작한 모든 모바일 앱은 단 하나의 네이티브 웹 뷰(WebView)를 핵심 매개체로 사용합니다. 웹 뷰를 활용하면 익숙한 어떤 프론트엔드 웹 기술로 앱 화면을 구현할 수 있습니다. 본질적으로 웹 페이지이므로 내장 브라우저가 모든 콘텐츠 렌더링을 담당합니다.

기본적으로 WebView는 화면 전체 보이는 영역을 채우지만 카메라 등 기능을 실행하면 카메라 화면이 일시적으로 WebView를 덮습니다.

NativePHP 핵심 구조: PHP 백엔드 + Vue, jQuery, 테일윈드 등 어떤 프론트엔드 스택과 혼합 개발

WebView는 항상 최상단에 표시되며 카메라, 내장 브라우저 등 전체 화면 모드일 때만 가려집니다. 사용자에게 보이는 모든 UI 화면은 전부 WebView로 처리됩니다.

NativePHP 모바일 하위 구조: 단일 WebView 컨테이너로 다중 네이티브 페이지 계층이 존재하지 않습니다. 즉 NativePHP에는 페이지가 단 하나뿐이며 모든 페이지 이동 및 뒤로 가기 동작은 동일한 WebView 내부에서 실행됩니다.

NativePHP 모바일 앱에는 언제나 딱 하나의 네이티브 WebView 컨트롤만 존재합니다. 앱의 모든 페이지 렌더링은 이 단일 웹 컨테이너 안에 담깁니다:

  • 페이지 전환, 라우터 변경, 이전 페이지 돌아가기, 팝업, 하위 페이지, SPA 전환 시 두 번째 WebView가 생성되지 않습니다. 이 설계로 메모리 사용량을 줄입니다.
  • 안드로이드/iOS 네이티브 페이지 스택, Activity/ViewController 계층 구조가 없습니다;
  • 보이는 여러 개의 ‘페이지’는 라라벨, 라이브와이어, 뷰 라우터 등 프론트 라우팅으로 동일한 WebView 내에서 DOM만 교체한 것으로 일반 웹 SPA 작동 방식과 완전히 동일합니다.

1 뷰포트 설정 (메타 태그로 화면 적응 제어)

모바일 웹 개발을 해본 사람이라면 이 설정을 모두 알고 있을 겁니다.

일반 브라우저와 마찬가지로 WebView는 뷰포트(표시 영역) 개념을 가지며 메타 태그로 제어하고 문법은 기존 웹 페이지와 동일합니다.

<meta name="viewport" content="width=device-width, initial-scale=1">Code language: HTML, XML (xml)

HTML 또는 블레이드 PHP 파일 head 영역에 이 메타 태그를 추가하세요. 요즘 거의 모든 웹사이트가 모바일 브라우저에 맞춰 이 설정을 적용합니다. 이 태그가 없으면 PC 화면 기준으로 렌더링되어 글자가 가늘고 레이아웃이 깨지는데 휴대폰은 DPI 해상도가 높기 때문입니다.

아무 사이트로 테스트해볼 수 있으며 예시로 NativePHP 공식 문서를 확인할 수 있습니다: Web View – NativePHP mobile v3 – NativePHP. 페이지 우클릭 후 소스 보기를 클릭하면 해당 태그를 확인할 수 있습니다.

이 설정은 두 가지 핵심 속성을 포함합니다:

width=device-width: 페이지 너비가 기기 물리 화면 너비와 일치

initial-scale=1: 초기 렌더링 비율 1:1, 자동 확대/축소 없음

2 두 손가락 줌 비활성화 (네이티브 앱 환경 구현)

안드로이드, iOS 순수 네이티브 앱은 두 손가락으로 화면을 확대/축소할 수 없지만 모바일 브라우저는 가능합니다. NativePHP 화면을 진짜 네이티브 앱처럼 만들려면 줌 제스처를 꺼야 합니다.

모바일 앱 개발 시 화면 표시를 정밀하게 통제해야 하므로 수동 줌을 막으면 완전한 네이티브 앱과 동일한 동작을 구현할 수 있습니다.

기존 뷰포트 태그에 아래 속성을 추가하세요:

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">Code language: HTML, XML (xml)

user-scalable=no: 수동 줌 제스처 비활성화

3 엣지 투 엣지 전체 화면 렌더링 (노치/곡면 화면 선행 설정)

UI 디자인 자유도를 최대화하기 위해 WebView는 기본적으로 화면 전체를 채웁니다. HTML/CSS/JS만으로 전경 어느 곳이든 콘텐츠를 배치할 수 있습니다.

하지만 화면 전체 영역을 전부 사용할 수는 없습니다. 대부분 기기는 전면 카메라 노치, 둥근 모서리, 곡면 테두리, 아이폰 다이나믹 아일랜드가 존재합니다. 이 영역은 뷰포트에 포함되지만 콘텐츠를 가리고 클릭할 수 없습니다.

특수 형태 화면에 대응하려면 메타 뷰포트 태그에 viewport-fit=cover를 추가하고 안전 영역 여백(Safe Area Insets) CSS 스타일과 함께 사용해야 합니다.

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, viewport-fit=cover">Code language: HTML, XML (xml)

viewport-fit=cover: 노치, 둥근 모서리를 포함한 화면 가장자리까지 페이지 렌더링을 확장합니다. 이 파라미터만으로는 콘텐츠가 노치에 가려지므로 아래 안전 영역 CSS와 필수로 함께 사용해야 합니다.

안전 영역 Safe Areas

안전 영역은 화면에서 가려지지 않는 보이는 구간을 의미합니다: 하드웨어 구조물(둥근 모서리, 카메라 노치, 다이나믹 아일랜드)과 상시 시스템 인터페이스(하단 제스처 바, 상태 표시줄)에 덮히지 않는 영역입니다.

기기가 자동으로 안전 영역 경계를 계산하고 세로/가로 화면 전환 시 동적으로 조절합니다. NativePHP는 내장 CSS 변수를 제공해 모든 기기에 맞는 적응형 레이아웃을 구현할 수 있습니다.

<!-- body에 전역 안전 영역 제약 적용 -->
<body class="nativephp-safe-area">
    <!-- 상단 네비게이션 바 좌우로 화면 둥근 모서리 여백 확보 -->
    <div class="fixed top-0 left-0 w-full bg-red-500 pl-[var(--inset-left)] pr-[var(--inset-right)]">
        상단 네비게이션 바
    </div>
</body>Code language: HTML, XML (xml)
  • --inset-top: 상단 안전 여백 (상태바 / 노치 높이)
  • --inset-bottom: 하단 안전 여백 (제스처 바 높이)
  • --inset-left: 곡면/둥근 모서리용 왼쪽 안전 여백
  • --inset-right: 곡면/둥근 모서리용 오른쪽 안전 여백

위 CSS 변수들은 NativePHP Mobile에 기본 탑재되어 프레임워크가 자동 주입하므로 별도 외부 CSS 라이브러리를 불러올 필요가 없습니다.

간편 전역 CSS 클래스: nativephp-safe-area

HTML 최상위 컨테이너에 이 클래스만 추가하면 모든 콘텐츠가 자동으로 안전 영역 내에 제한되어 개발 작업이 간소화됩니다. 위 예시 코드를 참고하세요.

공식 예시로 안전 영역 미적용 상태와 비교해 원리를 이해한 뒤 실 기기로 테스트하겠습니다. 먼저 안전 영역 설정 없는 코드 예시입니다:

<div class="fixed top-0 left-0 w-full bg-red-500>
    ...
</div>

이미지를 보면 상단 제목 바가 전면 카메라 노치에 완전히 가려지는 것을 확인할 수 있습니다.

가로 모드로 전환하면 상태가 더 안 좋아집니다. 아래 이미지를 참고하세요:

가로 화면일 때 좌우로 큰 빈 공간이 생기고 상단 바가 화면 전체를 채우지 못해 시각적으로 보기 좋지 않습니다.

안전 영역 설정을 적용하려면 body 태그에 기본 제공 클래스를 추가합니다:

<body class="nativephp-safe-area">
<div class="fixed top-0 left-0 w-full bg-red-500 pl-[var(--inset-left)] pr-[var(--inset-right)]">
    ...
</div>Code language: HTML, XML (xml)

화면 전체에 UI가 깔끔하게 맞춰지며 시각적 품질이 크게 개선됩니다.

코드 수정 실습

지난 시간 예시 파일인 welcome.blade.php를 수정하겠습니다.

body 내 전체 내용을 아래 코드로 교체하세요. 예시에서는 부트스트랩과 유사한 프론트 UI 라이브러리인 테일윈드를 사용합니다.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>{{ config('app.name', 'Mimi') }} - Built with NativePHP : welcome to foxdevelop.com</title>

    </head>
    <body>
        <div class="fixed top-0 left-0 w-full bg-red-500">
			상단 네비게이션 바
		</div>
    </body>
</html>
Code language: HTML, XML (xml)

파일 저장 후 명령 프롬프트에서 프로젝트 루트 폴더로 이동해 아래 명령을 실행하세요:

php artisan native:jumpCode language: CSS (css)
D:\phpproject\my-app>php artisan native:jumpCode language: CSS (css)

미리보기 주소: http://127.0.0.1:8000

PC 브라우저 미리보기로는 모바일 적응 효과를 확인할 수 없으므로 실제 기기로 테스트해야 합니다.

실기기 디버깅 절차

일반 안드로이드 앱 개발과 절차가 동일합니다: 안드로이드 휴대폰을 준비하고 USB 케이블로 컴퓨터에 연결한 뒤 휴대폰에서 개발자 모드를 활성화하세요. 활성화 방법은 인터넷 검색으로 쉽게 찾을 수 있습니다. 또한 구글에서 제공하는 ADB 툴을 설치해야 하는데 컴퓨터에서 휴대폰을 제어하는 도구로 안드로이드 스튜디오에 기본 포함됩니다.

안드로이드 스튜디오를 완전 설치하고 안드로이드 SDK, SDK 플랫폼 툴(ADB 포함)을 함께 설치하세요.

ADB 설치 정상 여부 확인:

터미널을 열고 명령 입력: adb devices

D:\phpproject\my-app>adb devices
List of devices attached
a34354354354352    deviceCode language: PHP (php)

위 출력 예시는 휴대폰이 정상 연결되었음을 의미합니다.

CMD에서 프로젝트 폴더로 진입 후 아래 명령을 실행해 안드로이드 앱 빌드 및 설치: php artisan native:run android

D:\phpproject\my-app>php artisan native:run android

  Running NativePHP for Android

 Build log: D:\phpproject\my-app\nativephp\android-build.log

  Updating Android configuration ....................................................................... 903.01ms DONE
  Copying Laravel source .................................................................................... 18s DONE
  Installing Composer dependenciesCode language: PowerShell (powershell)

빌드 과정에서 코틀린, 그래들 등 다양한 의존 패키지가 자동 설치되므로 안정적인 인터넷 환경이 필요합니다.

네트워크 프록시를 사용한다면 프로젝트 내 아래 경로 설정 파일을 수정하세요: D:\phpproject\my-app\nativephp\android\gradle\wrapper\gradle-wrapper.properties

그래들 다운로드 주소를 국내 미러 서버로 교체하는 예시:

#Mon Feb 10 07:33:27 EST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
#distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
distributionUrl=https\://mirrors.aliyun.com/maven/gradle/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Code language: Properties (properties)

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다