추가) PinchZoom이 가능한 Image Viewer 만들기 기능 수정

Heechan
HcleeDev
Published in
5 min readMay 30, 2021
Photo by Sigmund on Unsplash

이전 글: Swift: PinchZoom이 가능한 Image Viewer 만들기 | by Heechan | HcleeDev | May, 2021 | Medium

최근 PinchZoom이 가능한 Image Viewer 만드는 방법에 대해 소개한 적이 있다. SwiftUI 기능만으로는 만들 수 없어서, UIScrollView의 기능을 이용하기 위해 UIViewControllerRepresentable을 이용했다. 또한 SwiftUI의 기능을 이용한다는 가정하에 UIHostingController를 사용해 Image를 넘겨주었다.

하지만 그때 해결하지 못했던 버그가 하나 있었는데, 그 점을 해결해 짤막하게 적어보려고 한다.

세로로 긴 사진도 Fit하도록 수정함

본래 코드에서는 세로로 긴 사진을 넣을 시 제대로 정렬되지 않는 문제점이 있었다. 따라서 Constraint를 잡을 때 뭔가 잘못된 것이 아닐까 싶었고, 그 부분에서 뭔가 잘못된게 없는지 확인해보았다.

일단 지난 코드를 보자.

여기서는 alignment()를 init에서 불러주고 있고, viewDidAppear에서는 recenter()만 호출하고 있다.

이때 hostedView의 크기를 확인해보기 위해 init과 viewDidAppear에 각각 print문으로 로그를 찍게 만들었다. 만약 init에서 hostedView의 크기가 제대로 잡힌 것이 아니라면 alignment() 함수가 불러져와봤자 큰 의미가 없다고 생각해 체크해보았다.

hostedView size in init: (0.0, 0.0, 0.0, 0.0)
hostedView size in viewDidAppear: (0.0, 0.0, 147.0, 600.0)

띠용? init에서는 hostedView의 크기가 (0, 0)으로 나왔다. viewDidAppear에는 크기가 (147, 600)으로 나오는 것을 확인할 수 있다.

bounds를 출력한 것이기 때문에 첫 두 개는 좌표, 뒤 두 개가 너비와 높이를 의미한다.

이는 hostingController 안의 이미지가 제대로 로드되기 전에 init이 일어나기에 생기는 현상으로 보인다. 이 상태에서 alignment() 함수를 호출해봤자 의도대로 진행되지 않을 것이다.

따라서 alignment 함수를 viewDidAppear로 옮겨주는 작업을 진행했다.

우선 alignment() 함수도 살짝 변경했다. 원래 조건에 맞추어 center constraints를 맞추도록 했는데, init에 있을 때는 hostedView의 사이즈가 (0, 0)이었기에 의미없는 조건문이 되었었다. 옮기면서는 조건에 따라 x, y축 중 한 쪽만 맞추는 것이 아니라 양 쪽 다 맞추도록 수정했다.

또한, viewDidAppear에 alignment()를 이동하고, init에 있던 alignment()와 recenter()를 삭제했다.

수정한 코드의 viewDidAppear에는 DispatchQueue가 달려있다. 이 구문을 잘 보면 현재로부터 0.1초 후까지 recenter()와 alpha 값 조정이 실행되도록 한 것을 알 수 있다. 이 이유는 setNeedsUpdateConstraints() 때문이다.

recenter가 제대로 적용되려면 Image가 다 로드되고 alignment()까지 제대로 실행된 후여야 하나, 저 DispatchQueue로 후순위 작업으로 미뤄두지 않는다면 의도대로 움직이지 않는다.

우리는 alignment로 constraints를 조정해두고, setNeedsUpdateConstraints()를 이용해 ‘이 ViewController는 Constraints 재조정이 필요합니다~’라고 스케쥴러에 알려두는데, 이 스케쥴러는 60분의 1초 주기로 돌아간다. 따라서 60분의 1초가 돌기 전에 recenter()가 실행된다면 업데이트가 되지 않은 상태, alignment 조정 전 상태에서 recenter가 실행되는 것이라 의미가 없어진다.

따라서 0.1초의 딜레이를 줌으로써 recenter 및 alpha 값 조정이 우리의 의도대로 실행될 수 있도록 했다.

결과물은 이렇게 나온다. 세로로 긴 사진도 제대로 Fit되어 보여진다.

결론

이걸로 당장 큰 기능상 문제는 없어졌다만, 그래도 자주 사용하는 앱들의 이미지 뷰어에는 모자란 점이 사실이다. 아직 내가 UIKit을 몰라서 부족한 것으로 생각되기는 하는데, 일단 이 상태에서 더 발전할 수 있는 점을 꾸준히 찾을 예정이다. 실제로 내가 만드는 앱에서 이 기능을 사용하는데, 아직 사용성 측면에서 그렇게 좋지는 않은 것 같다…

이번 주는 평일 내내 골골 앓느라 글을 좀 써두지 못해서… 주말에 급히 쓰느라 힘들었다.

--

--

Heechan
HcleeDev

Junior iOS Developer / Front Web Developer, major in Computer Science