상세 컨텐츠

본문 제목

아이폰 safe area 영역 대응 env(safe-area-inset-*)

개발

by 베르월드 2023. 7. 7. 13:22

본문

이번 새로운 프로젝트는 하이브리드 웹앱을 진행하였다

근데 앱 배포하면서 IOS safe area 대응해야 하는 문제에 직면했다.

 

IOS에서는 safe area 영역을 디바이스 화면으로 잡기 때문에 top: 0, bottom: 0으로 fixed로 고정해줬을 때 올바르게 적용이 되지 않는 문제가 발생하였고 100vh가 제대로 먹히지 않는 문제가 발생하였다.

 

(왼) top: 0이 제대로 적용되지 않음 / (오) 100vh로 채우고 스크롤을 하면 body 영역이 넘쳐있음 

 

 

 

가장 큰 문제점 --vh 미적용

모바일 브라우저에서 URL 입력 영역과 하단 네비게이션 영역의 사이즈를 포함하고 있어 100vh를 했을 경우 스크롤이 생기는 현상을 해결하기 위해 --vh라는 속성을 자바스크립트로 계산하여 디바이스의 1/100 값으로 지정해줄 수 있다.

이렇게하면 100vh가 모바일 브라우저 환경마다 딱 맞게 된다

 

 

2. 해결 방안

 

총 3번의 실행착오(?)를 거쳐서 해결할 수 있었다.

 

1) safe-area 지정

위에 사진 중 왼쪽 top:0; 으로 고정되지 않는 문제점을 해결하기 위해 css도 확인하고 xcode로 실행해서 확인도 해봤지만 도저히 해결할 수 있는 문제가 아니었다.

결국 다른 앱 개발자 분에게 자문을 구했고 safe area가 제대로 적용하지 않은 문제로 확인되어 정상적으로 노출될 수 있게 되었다.

 

2) env()

위에는 앱 개발자 분이 해결을 해주셨지만 앱에서 스크롤이 넘치는 부분 해결하기 위해 env(safe-area-inset-*)을 사용했다.

IOS 앱 때문에 vh 적용된 부분은 css로 전부 수정을 해줘야하는 노가다성 일이 생겨버렸다.

 

솔직히 이게 딱 된다고 하면 문제가 안됐는데 될지 안될지는 앱 배포를 해보고 확인을 해봐야 알 수 있는 상황이었기에 막막했지만

 

 

여기서 꿀팁

 

공유가 가능할지는 모르겠지만 앱 소스를 받을 수 있다면 xocde로 빌드하면 시뮬레이터로 확인할 수가 있다.

그리고 우리 프로젝트는 하이브리드 웹앱이기때문에 웹주소로 연결해둔 소스가 있을건데 그 주소를 내가 사용하는 IP로 연결하면 내가 수정한 내용을 앱 배포한 것처럼 확인을 할 수 있다!

그리고 나서 safari에서 개발자용을 클릭하면 시뮬레이터 개발자도구를 킬 수 있다

 

 

env 속성 사용 전 먼저 메타 태그에 viewport-fit=cover를 추가해줘야 한다.

app: {
    head: {
      title: process.env.TITLE,
      script: [],
      link: [],
      meta: [
        { name: "viewport", content: "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" },
  
      ]
    }
  },

 

위와 같이 설정해주면 viewport를 스크린의 전체로 확대할 수 있다.

 

이러고 나서 env() 속성을 설정해주면 된다.

env(safe-area-inset-top))
env(safe-area-inset-bottom));
env(safe-area-inset-left));
env(safe-area-inset-right));

 

많은 블로그를 보았지만 위와 같은 내용만 있지 뭘 어떻게 쓰는지 감이 안잡혔다..

 

적용 예시는 아래와 같다.

body{
 margin-top: env(safe-area-inset-top);
 min-height: calc(var(--vh, 1h) * 100 - env(safe-area-inset-top)); 
}


@supports (position: fixed) {
 .main-header{
  position: fixed;
  top: env(safe-area-inset-top);
 }
}

 

이런식으로 전체적으로 css를 수정하였고 xcode에서도 정상적으로 시뮬레이터가 작동하는 걸 확인하였다.

 

그런데 막상 IOS 앱에 배포를 해보니 화면은 꽉 찼지만 --vh 자바스크립트 함수가 safe area 영역을 제외하고 --vh 가 계산되어 실제 100vh보다 작게 나오는 것이었다.

 

 

 

3) 아이폰 앱에서는 --vh 함수 제외

--vh 함수는 모바일 웹에서 필요없는 영역을 제외하고 1/100 높이값을 계산하는 거라 필요하고

IOS 앱에서는 --vh가 아닌 1vh로 해야 100%로 화면이 꽉차는 거다.

이 문제를 해결할 수 있는 방법은 아이폰 앱에서는 --vh를 1vh로 넣는 방법 밖에 없었다.

 height: calc(var(--vh, 1vh) * 100);

위에 css를 해석하자면  --vh가 적용이 안되는 경우 1vh로 적용시키라는 건데

실질적으로 IOS앱에서는 계산이 이상하게 될 뿐이지 --vh가 계산이 안되는 건 아니었다.

 

 

그래서 mounted에 아래와 같은 코드를 작성하였다

    if (IOS 앱일 때) {
      document.documentElement.style.setProperty("--vh", "1vh");
    } else { // IOS 앱이 아닌 경우
      const vh = window.innerHeight * 0.01;
      document.documentElement.style.setProperty("--vh", vh + "px");
      window.addEventListener("resize", function () {
        const vh = window.innerHeight * 0.01;
        document.documentElement.style.setProperty("--vh", vh + "px");
      });
    }

 

 

이러니 최종적으로 해결되었다.

 

 

이렇게 또 알게된 게 있어서 좋긴 했지만 해결하는 동안 너무 힘들었다... 

IOS 진짜 싫다...

 

 

관련글 더보기