상세 컨텐츠

본문 제목

UIStackView View 겹치기

iOS

by 쑤야. 2022. 11. 7. 22:38

본문

1. Problem

 

아래 2가지의 디자인을 보면 아이콘들이 겹쳐져 있는 것을 볼 수 있다.

 

하지만 평소 UIStackView를 사용할 때는 아래 디자인들과 같이 View끼리의 겹침 현상이 발생하지 않고, 일정 간격으로 벌어져 있는 상황만 구현해보았기 때문에 고민과 구상이 조금 필요했다.


2. Search and Think

 

위의 디자인을 보고 어떻게 구현해볼까 고민하다가 아이콘 크기, view 간 spacing 등이 똑같고 안에 이모지의 종류만 달라지는 것이기 때문에 UIStackView를 사용해야겠다고 판단을 하게 되었다.

 

    * UIView안에서 addSubview의 순서 조정을 통해 View의 레이아웃을 잡는 방식도 가능하겠지만.. 간격이 동일하므로 UIStackView를 쓰는 게 더 적합할 것이라 생각한다.

 

먼저 겹쳐지는 현상에 대해서는 UIStackView에서 View들 간의 spacing을 조정할 때 사용하던 프로퍼티인 spacing에 음수값을 넣으면 되지 않을까 생각했다.

 

let reactionStackView = UIStackView().then{
    $0.spacing = -6
    $0.axis = .horizontal
}

reactionStackView.addArrangedSubview(myReactionBtn)
reactionStackView.addArrangedSubview(anotherReactionBtn)
reactionStackView.addArrangedSubview(theOtherReactionBtn)

 

위의 코드를 실행해본 결과, View끼리 겹침은 성공했지만, 아래 사진처럼 내가 의도한 것과는 반대로 왼쪽부터 View가 쌓인 것을 확인할 수 있었다.

 

이유는 Stack 구조를 알고 있다면 쉽게 이해될 것이다.

UIStackView는 View를 Stack 구조에 하나씩 쌓는 것이므로, 가장 늦게 넣는 View가 맨 위에 쌓이게 되기 때문이다.

 

일반적인 방법인 addArrangedSubview로 해결이 안 된다면,

 

  1. View를 넣는 순서를 변경
  2. 넣는 방향을 변경

위의 2가지 방안을 먼저 구상하고 UIStackView 문서를 찾아보니, insertArrangedSubview라는 메서드를 발견하게 되었다.

 

# insertArrangedSubview

: 지정한 index에 parameter로 넘긴 View를 추가해주는 메서드로, stack 구조이므로 index 값은 stack의 사이즈를 넘기면 안 된다.

open class UIStackView : UIView {

		/*
     Adds the view as a subview of the container if it isn't already.
        Updates the stack index (but not the subview index) of the
     arranged subview if it's already in the arrangedSubviews list.
     */

    open func insertArrangedSubview(_ view: UIView, at stackIndex: Int)

}

3. Solution and Apply

 

reactionStackView.insertArrangedSubview(theOtherReactionBtn, at: 0)
reactionStackView.insertArrangedSubview(anotherReactionBtn, at: 0)
reactionStackView.insertArrangedSubview(myReactionBtn, at: 0)

 

위의 코드와 같이 addArrangedSubview가 아니라 insertArrangedSubview를 활용해 가장 오른쪽의 view부터 0번째 인덱스에 하나씩 추가를 해줄 경우 아래 사진과 같은 결과물을 얻을 수 있다.

 * 첫 번째로 넣는, 가장 오른쪽 View를 넣을 때는 insertArrangedSubview가 아닌 addArrangedSubview로 넣어도 되지만.. 나는 그냥 통일성을 위해 insertArrangedSubview를 사용했다

reactionStackView.addArrangedSubview(theOtherReactionBtn)
reactionStackView.insertArrangedSubview(anotherReactionBtn, at: 0)
reactionStackView.insertArrangedSubview(myReactionBtn, at: 0)

4. Result

 

UIStackView에서 View 겹침을 위해서는

 

  1. spacing 값 음수 적용
  2. 만약 왼쪽이 top에 위치하길 원하는 경우, insertArrangedSubview 활용

디자인 적용 결과물은 UI 구현이 모두 완료되면 수정해놓도록 하겠다..^^ (아직 UI 기본 틀 작업 중이므로..)

관련글 더보기