티스토리 뷰

Frontend

iPhone 해상도에 따른 UI 이슈

지마켓 강수진 2021. 1. 26. 16:08

안녕하세요! BXP POD에서 iOS 개발자로 일하고 있는 강수진입니다. 🙋🏻‍♀️

개발 과정에서 아래와 같이 디바이스에 따라 아이템 UI 일부가 잘려 보이는 이슈가 있었습니다.

결론부터 말씀드리면 기기에 따른 해상도 때문에 생기는 문제였는데요, 지금부터 깨달음의 내용과 해결 과정을 공유해보고자 합니다.

요구 사항

  • CollectionView의 left와 right margin은 16
  • itemSpacing은 8
  • 아이템 width는 각각 남는 영역의 1/2로 가변적

요구 사항은 위와 같았고, 이에 맞게 열심히 구현을 했습니다.👩🏻‍🏭🛠

문제 사항

하지만 곧 QA 하는 과정에서 이슈가 들어오게 됩니다.

"아이템 corner 쪽이 각져서 잘려보이고, 아이템 사이 간격은 8.3처럼 보여요!"

네?? 좀 더 자세히 살펴봅시다.

다른 그림 찾기도 이렇게는 안내겠어요,, ◠‿◠

잘려서 각져보이는 부분이 보이시나요? 그런데 또 문제는 "제거에선 원래대로 잘 보이는데요? 🤔"라는 거죠.

결론적으로는 초반에 말씀 드렸듯 기기에 따른 해상도 문제였는데요, 왜 이런 현상이 발생한 건지 자세히 알아봅시다.

iPhone의 해상도

iPhone은 기기 별로 해상도가 다릅니다. 당연히 고해상도(High-resolution) 기기일수록 더 선명히 보입니다.

이미지 출처:  https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/image-size-and-resolution/

고해상도라는 말은 "포인트 당 픽셀 밀집도가 높다"는 의미입니다. (포인트는 1 인치의 1/72 값으로, 대략 0.3527mm에 해당하는 절댓값)

그림과 같이 동일한 1pt에 대해 모여있는 px 수가 다른 것을 확인할 수 있고, iPhone은 기기에 따라 1x, 2x, 3x라는 세 가지 종류의 해상도를 가집니다.

그럼 제 UI는 해상도에 따라 어떻게 px로 표현될까요?

요구사항에 해당하는 픽셀 값을 해상도 별로 나타내면 다음과 같습니다. 절댓값인 pt 는 같지만 한 변에 들어갈 수 있는 px은 두배, 혹은 세배가 됩니다.

그런데 여기서 문제가 발생합니다. 1x나 3x 상황을 보면 아이템의 width px값은 0.5로 떨어지는데, 픽셀이란 "화면을 구성하는 가장 기본이 되는 단위"이기 때문에 0.5는 표현할 수 없습니다.

💡 Px 는 화면을 구성하는 가장 기본이 되는 단위. 따라서 0.5를 표현할 수 없다

그럼 내부적으로 어떻게 동작하는데요?

1x 에서도 0.5로 떨어지긴 하지만, iPhone 4S에 도입된 Retina Display 이후로는 최소 2x 이상으로 렌더링이 되니, 3x 기준으로 작성하겠습니다.

3x 기준으로, 예상 px 값은 아래 그림과 같습니다.

하지만 방금 말씀 드렸듯, 0.5px 은 처리할 수 없기 때문에 반올림을 하여 503px로 만듭니다.

여기서 조정된 px값을 모두 더해봅시다.

48+503+24+503+48 = 1126

가로 375 기준, 3x 렌더링을 하는 기기가 가질 수 있는 최대 픽셀 수는 375*3 = 1125입니다. 하지만 방금 보았듯 아이템 width가 반올림되어서 계산된 값은 1126px으로 1px이 초과됩니다.

따라서 다시 502로 재단합니다. 처음부터 502로 내림하지 않고 503으로 반올림을 먼저 한다고 파악한 이유는, 아이템의 비율을 1:1로 맞춰놨는데 이때 height가 503px이었기 때문입니다.

 

아이템의 width가 502px로 조정된 px값을 다시 더해봅시다.

48+502+24+502+48 = 1124

이번에는 1125(375*3)에 비해 1px이 남게됩니다.

따라서 남는 여백을 채우기 위해 가운데를 임의로 늘리게 됩니다.

그래서 왜 그랬던 거라고요?

다시 처음으로 돌아가서 문제 상황과 원인을 매치해봅시다.

  • 아이템 corner 쪽이 각져서 잘려 보여요 → 503(502.5에서 반올림) px에서 cornerRadius가 반영된 상태에서 502px로 줄어들었기 때문입니다.
  • 아이템 사이 간격은 8pt가 아니라 8.3pt처럼 보여요! → 3x 기준으로 item의 interSpacing이 25px인데, 이를 375 기준으로 맞추면, 즉 /3을 하면 8.333333 값이 나오기 때문입니다.
  • 근데 제거에선 잘되는데요? → 저는 2x 기기로 테스트해서 width로 0.5가 안 떨어지는 상황이었습니다. 하지만 QA 기준이 되는 폰은 iPhone 11 Pro로 3x 렌더링 기준을 갖고 있었기 0.5가 떨어져서 위와 같은 과정이 발생했기 때문입니다.

해결 방안

아이템 카드 width의 계산식은 "(전체 디바이스 너비 - 마진 너비) / 아이템 카드 개수"입니다.

이때 제가 가진 아이템 카드 개수는 2개로 고정되어 있으므로 아래와 같은 상황에서 카드의 width가 소수점으로 떨어지게 됩니다.

  • 디바이스 width가 홀수면서 마진 전체 width가 짝수 일 때
  • ex. 디바이스 width = 375, 마진 전체 width = 16+8+16 = 40 & 아이템 카드 width = (375-40)/2 = 167.5
  • 디바이스 width가 짝수면서 마진 전체 width가 홀수일 때아이템 카드 width = (414-41)/2 = 186.5
  • ex. 디바이스 width = 414, 마진 전체 width = 16+9+16 = 41

따라서 Item의 interSpacing을 디바이스의 width가 홀수일 때는 홀수, 짝수일 때는 짝수로 대응하는 방향으로 문제를 해결했습니다.

그러면 어떻게 될까요?

Device width 홀수일 때 (ex. 375)

  Left Margin Item1 Inter Spacing Item2 Right Margin
1x 16 167 9 167 16
2x 32 334 18 334 32
3x 48 501 27 501 48

Device width 짝수일 때 (ex. 414)

  Left Margin Item1 Inter Spacing Item2 Right Margin
1x 16 187 8 187 16
2x 32 374 16 374 32
3x 48 561 24 561 48

이렇게 Device의 width가 홀수이든, 짝수이든 간에 item의 width가 0.5로 떨어지는 경우 없게 됩니다.

결론

아이폰의 해상도에 따라 의도하지 않은 상황이 발생할 수 있다는 걸 인지하고, 디자인 및 개발 과정에서 한번 더 고려하면 도움이 될 듯합니다.

읽어주셔서 감사합니다~!

댓글