daumPostcode / QnA

Daum 우편번호 서비스 Q&A
http://postcode.map.daum.net/guide
93 stars 13 forks source link

Android - Chrome custom tabs - 팝업 오픈시 헤더에 입력창이 가리는 현상 #1087

Open ndjkwon opened 11 months ago

ndjkwon commented 11 months ago

안녕하세요.

Android 앱에서 외부 서비스를 호출할 때 Chrome Custom Tabs를 사용하고 있습니다. Chrome Custom Tabs에서 열린 해당 외부 서비스에서 Daum Postcode Service를 팝업으로 호출하는데요. 해당 팝업이 열린 후 최상단 입력창을 포커싱하면 화면 헤더에 입력창이 가리는 현상이 있습니다. (기본 브라우저가 Samsung Internet Browser 일 때만 발생)

동영상 : https://drive.google.com/file/d/12qdgEU55JSrCRBRMXnugvBGUaKpwrrJ3/view?usp=drivesdk

해당 현상 개선하려면 외부 서비스 쪽에 어떻게 가이드를 해야 할까요?

daumPostcode commented 11 months ago

@ndjkwon 안녕하세요~. 이 부분은 삼성 브라우저의 이슈일 확률이 99프로 입니다. 저희가 이부분을 제어할 수 있는지는 확실치 않습니다. 키보드가 올라오면서, 스크롤 위치를 변화시키는건 브라우저거든요.

확인을 해보겠으나 수정여부는 지금으로써는 말씀드릴 수가 없을 것 같습니다. 현재 안드로이드 버전, 삼성브라우저 버전을 알려주시기 바랍니다.

그리고 추가적으로 모바일에서 주로 열리는 서비스라면, 되도록 layer 모드를 이용하시는 것을 추천드립니다.

ndjkwon commented 11 months ago

@daumPostcode 확인 감사합니다. 안드로이드 13, 삼성 인터넷 버전은 23.0.0.47 (최신버전) 입니다.

삼성 인터넷 브라우저를 직접 열어서 팝업 호출시에는 문제가 없는데, Chrome Custom Tabs를 사용하였을 때만 이슈가 있습니다. PC에서도 동일 화면을 사용하고 있기도 하고, 여러 문제로 팝업 모드를 사용하고 있습니다.

수정 검토에 필요하신 내용이 있으시면 말씀 부탁드립니다.

daumPostcode commented 11 months ago

@ndjkwon 한가지 더 궁금한게 있습니다. 크롬커스텀탭이라면, 바로 OS레벨에서 테스트가 불가하고 하나의 앱을 만들고 그 안에다가 웹뷰?를 올려서 테스트 해야 되는 부분일까요? 이러한 경우에는 제가 앱개발자가 아니라서 테스트도 시간이 걸리지만, 정확한 환경 재현은 불가능 할 수 있습니다. 제가 원인을 발견해도 이에대한 JS레벨에서의 처리가 불가능 할 수 있기 때문에, App차원에서도 해결책을 검토해 주시면 감사하겠습니다.

ndjkwon commented 11 months ago

@daumPostcode 네, 크롬커스텀탭으로 URL 호출하도록 앱을 만들어서 확인이 필요할 것 같습니다.

상단 입력창이 가려지는 현상을 근본적으로 수정할 수는 없더라도, 스크롤이라도 가능해서 팝업 첫 화면에서 스크롤을 내릴 수만이라도 있다면 좋겠습니다. ㅠㅠ

이리저리 시도해보니, 팝업창이 검색결과를 노출하며 한번 스크롤 가능해진 이후에는, 가려지는 현상이 없어지거든요.

참고 > https://drive.google.com/file/d/131G3bTu_31Jc8TjSNQBczKQ1IQOcRw4i/view?usp=drivesdk

daumPostcode commented 10 months ago

@ndjkwon 안녕하세요~

이리저리 업무가 많아 변명같지만;; 늦게 답변드려 죄송합니다.

해당 이슈를 현재의 open()메소드를 사용하는 상태 그대로 해결하기는 좀 어려워 보입니다. 특수한 브라우저, 그것도 크롬커스텀탭에서만 발생하는 이슈라, 최상단에 margin이나, padding이나, 또는 특정 DOM으로 영역을 주면 가리는걸 막을 수는 있으나,

이를 다양한 환경에서 돌아가는 서비스 코드에 넣기에는 무리가 좀 있습니다.

그래서 이러한 경우에 제가 예전에 해결책을 다른 분들께 드린 케이스가 있는데,

embed를 사용한 레이어모드를 이용하되, popup을 직접 구현하시는 것입니다. 그럼 이 팝업창에서, 삼성브라우저 커스텀탭일 경우에만 특정한 조작을 수행하면 될것 같습니다.

팝업창을 직접 만들면, 자신의 페이지이기 때문에, 해당 팝업창을 열때, 일반 브라우저인지, 커스텀탭이라면, 커스텀탭을 구동하는 명시적인 코드가 존재하기 때문에, 이때 특정 파라미터나 값을 넘겨서, 팝업창에서 받고, 커스텀탭이 삼성브라우저일경우 UA에 samsung 이라는 단어가 들어가니, 이 두가지 조건으로 해당페지에 조치를 취하면 될것 같습니다.

추가로 window.addEventListener('resize', callback) 이벤트의 경우 키보드가 올라오면, 화면 사이즈가 변해서 자동으로 리스너가 실행이 되기 때문에; 페이지에 첫 접속시 윈도우 높이를 체크했다가, 그것보다 작으면 상단에 margin을 붙히고, 그게 아니라면 margin 을 다시 없애고 하는 방식으로 어느정도 처리가 될것 같습니다.

즉,

  1. 크롬 커스텀탭에 A라는 사이트가 열리는 경우, 이 A라는 사이트에서 우편번호 서비스 팝업을 이용하려할때
  2. B라는 팝업페이지를 직접 만들어서, B라는 팝업페이지를 A페이지에서 window.open함수로 실행한다.
  3. B라는 페이지가 팝업으로 뜨면, B 페이지에서는, 페이지가 뜨자마자, 우편번호서비스의 embed함수를 통해 팝업페이지에 꽉차는 레이어로 화면을 띄운다. (가이드 페이지의 페이지에끼워넣기 예제 참고)
  4. 검색후 주소를 선택하면 oncomplete콜백이 실행되는데, 여기서, 콜백함수로 전달된 데이터를 opener.XX(XX는 사용자가 정의한 A페이지에 존재하는 함수) 함수에 데이터를 전달한다.
  5. A페이지에서 데이터를 받으면, window.open을 실행할때 리턴되는 객체.close()함수를 통해 팝업페이지를 닫는다.

이렇게 실행되게 하시면 됩니다.

그리고 상단에 margin을 주는 그러한 코드는 popup페이지에서 처리를 하면 될것 같습니다.

//A 페이지
function openSample() {
    var popup = window.open("/views/postpopup", "sample_popup", "width=570,height=420,scrollbars=yes,resizable=yes");

    window.oncomplete = function (data) {
        console.log(data);

        document.getElementById('sample4_roadAddress').value = data.roadAddress;
        popup.close();
    }
}

//B페이지(팝업)
var ua = navigator.userAgent.toLowerCase();

var baseSize = window.outerHeight;
window.addEventListener('resize', function() {
    if (ua.indexOf('samsung')) {
        var wrap = document.getElementById('wrap');
        if (baseSize > window.outerHeight) {
            wrap.style.marginTop = '48px';
        } else {
            wrap.style.marginTop = '0px';
        }

    }
})

new daum.Postcode({
    oncomplete: function(data) {
        opener.oncomplete(data);
    },
    onresize : function(size) {
        element_wrap.style.height = size.height+'px';
    },
    width : '100%',
    height : '100%'
}).embed(element_wrap);

위는 대략적인 테스트 코드입니다. 아무튼 저희가 직접 띄우는 open() 함수를 사용하지 않고, 개발자가 직접 팝업을 만들고, 그 팝업페이지안에 embed()로 화면을 꽉채우면, 사용자가 보기에는 팝업으로 보이기 때문에, 사용성과 관련된 이슈는 없을 것이라 봅니다.

한번 참고해 주세요.