이번 새로운 프로젝트는 하이브리드 웹앱을 진행하였다
근데 앱 배포하면서 IOS safe area 대응해야 하는 문제에 직면했다.
IOS에서는 safe area 영역을 디바이스 화면으로 잡기 때문에 top: 0, bottom: 0으로 fixed로 고정해줬을 때 올바르게 적용이 되지 않는 문제가 발생하였고 100vh가 제대로 먹히지 않는 문제가 발생하였다.
모바일 브라우저에서 URL 입력 영역과 하단 네비게이션 영역의 사이즈를 포함하고 있어 100vh를 했을 경우 스크롤이 생기는 현상을 해결하기 위해 --vh라는 속성을 자바스크립트로 계산하여 디바이스의 1/100 값으로 지정해줄 수 있다.
이렇게하면 100vh가 모바일 브라우저 환경마다 딱 맞게 된다
총 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 진짜 싫다...
최신 업데이트 된 새로운 CSS기능들 (0) | 2023.07.19 |
---|---|
데이터베이스 작동 원리 이해하기 (0) | 2023.07.14 |
[DeadLock] 데드락 ( 교착 상태 ) (0) | 2023.07.03 |
[Nuxt3] Nuxt3의 Options API (asyncData, head, defineNuxtComponent) (0) | 2023.06.24 |
[springboot] Referer 헤더와 사용법 (현재페이지 이전에 방문한 사이트 url 확인하기) (0) | 2023.06.19 |