stack.addArrangedSubview

이원희·2021년 1월 19일
2

📱 iOS

목록 보기
13/24
post-thumbnail

오늘은 UIStackView에 어떻게 view를 추가할 수 있는지 알아보자.
포스팅 제목이 addArrangedSubview vs addSubView이다.
이렇게 정한 이유는 StackView에 동적으로 subView들을 추가할때 헷갈렸던 부분이기도 했고, 그때는 자세하게 이해하고 넘어갈 생각을 하지 않았어서 이제와서 해보려 한다..!ㅋㅋㅋ

UIStackView

iOS 개발을 하다보면 UIStackView를 많이 사용하게 된다.
처음부터 모든 콘텐츠를 알 수 있다면 좋겠지만 UIStackView 안의 view들을 다이나믹하게 관리해야할 때가 있다.
그럴때는 보통 코드를 통해 UIStackViewsubView를 추가하게 된다.

공식문서로 UIStackView에 대해서 알아보자
(출처: https://developer.apple.com/documentation/uikit/uistackview)

StackView를 사용하면 오토레이아웃의 기능을 활용하여 기기의 방향, 화면 크기 및 사용 가능한 공간의 모든 변경 사항에 동적으로 적용할 수 있는 사용자 인터페이스를 만들 수 있다.
StackViewarrangedSubviews 프로퍼티로 모든 view들의 레이아웃을 관리한다.
arrangedSubviewsStackView의 axis에 따라 정렬되어 있다.

arrangedSubview라는 프로퍼티로 StackView 안의 view들을 관리한다는 것을 알았다.


arrangedSubviews

공식문서로 arrangedSubviews를 확인해보자.
(출처: https://developer.apple.com/documentation/uikit/uistackview/1616232-arrangedsubviews)

arrangedSubviews는 정렬된 스택뷰의 뷰들 리스트라고 한다.

위의 그림처럼 1, 2, 3이라는 view들을 subView로 갖는 vertical stack view가 있다고 생각해보자.
위의 vertical stack viewarrangedSubviews 프로퍼티는 [1, 2, 3]일 것이다.
arrangedSubviews 프로퍼티는 스택뷰의 뷰들의 리스트이고, 스택 뷰의 축의 방향에 따라 정렬된 값을 갖기 때문이다.


subview 추가하기

addArrangedSubview(_:)insertArrangedSubview(_:at:)로 스택뷰에 subView를 추가할 수 있다.


addArrangedSubview(_:)

공식문서로 addArrangedSubview(_:)를 확인해보자.
(출처: https://developer.apple.com/documentation/uikit/uistackview/1616227-addarrangedsubview)

addArrangedSubview(_:)arrangedSubviews 배열의 끝에 뷰를 추가하는 메서드이다.

이 메서드는 파라미터로 입력 받은 뷰가 이미 스택 뷰의 subView가 아닌 경우 스택 뷰의 subView로 자동 추가한다.
즉, 이미 스택 뷰의 subView인 경우에는 순서를 변경하지 않는다.


그렇다면 stackView에 subView를 추가해보자.

    @IBOutlet weak var stack: UIStackView!
    
    override func viewDidLoad() {
        let blueView = makeView(.blue)
        stack.addArrangedSubview(blueView)
    }
    
    private func makeView(_ color: UIColor) -> UIView {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = color
        view.heightAnchor.constraint(equalToConstant: 200).isActive = true
        return view
    }

필요한 subView를 만들어 반환하는makeView(_:) 메서드를 정의했다.
blue를 배경색으로 갖는 뷰를 스택 뷰에 추가했다.

우리가 원하는대로 파란 배경색을 갖는 뷰가 스택 뷰에 추가되었다.


이미 스택 뷰의 subView인 뷰를 추가하면 어떻게 될까?

이 메서드는 파라미터로 입력 받은 뷰가 이미 스택 뷰의 subView가 아닌 경우 스택 뷰의 subView로 자동 추가한다.

이 메서드에 대해 설명하면서 위와 같은 설명도 덧붙였다.
설명대로라면 이미 스택 뷰의 subView인 뷰를 addArrangedSubview(_:)한다면 아무 일도 안 일어날거 같다.
한 번 확인해보자.

   @IBOutlet weak var stack: UIStackView!
    
    override func viewDidLoad() {
        let blueView = makeView(.blue)
        
        stack.addArrangedSubview(blueView)
        stack.addArrangedSubview(blueView)
    }
    
    private func makeView(_ color: UIColor) -> UIView {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = color
        view.heightAnchor.constraint(equalToConstant: 200).isActive = true
        return view
    }

blueView를 두 번 addArrangedSubview(_:)해봤다.

결과는 아까와 동일하게 나타난다.
배경색이 같아서 확인이 안되는거일수도 있으니 다시 자세하게 확인해보자.

stackViewUIView가 하나만 들어가 있는 모습을 확인할 수 있다.


insertArrangedSubview(_:at:)

공식문서로 insertArrangedSubview(_:at:)를 확인해보자.
(출처: https://developer.apple.com/documentation/uikit/uistackview/1616237-insertarrangedsubview)

입력 받은 인덱스에 입력 받은 뷰를 정렬된 subView들의 배열에 추가한다.

스택 뷰의 arraySubViews에 이미 존재하는 인덱스라면 arraySubViews 배열의 크기를 늘리고 입력 받은 인덱스의 자리를 비우기 위해 해당 인덱스부터 subView들의 자리를 한 칸씩 뒤로 이동한다.
인덱스에 입력 받은 뷰가 들어갈 자리를 마련하고 스택 뷰는 입력 받은 뷰를 해당 인덱스에 저장한다.


subView 제거하기

removeArrangedSubview(_:) 스택뷰에서 subView를 제거할 수 있다.


removeArrangedSubview(_:)

공식문서로 removeArrangedSubview(_:)를 확인해보자.
(출처: https://developer.apple.com/documentation/uikit/uistackview/1616235-removearrangedsubview)

removeArrangedSubview(_:)arrangedSubviews 배열에서 입력받은 view를 제거하는 메서드이다.

이 메서드를 통해 제거된 뷰들의 위치와 크기는 더 이상 스택 뷰에서 관리되지 않는다.
이 메서드로 UIStackViewarrangedSubviews 배열에서 입력 받은 뷰를 제거할 수는 있지만 그 뷰는 계속 뷰의 hierarchy에 남아 있는다.


코드로 이해해보자.

위의 그림처럼 파란색, 초록색 배경색을 가진 뷰들을 stackViewsubView로 추가했다.
stackViewarrangedSubviews 프로퍼티에 두개의 뷰가 출력되는걸 확인할 수 있다.
그렇다면 이제 removeArrangedSubview(_:)로 파란색 배경색 뷰를 제거해보자.

removeArrangedSubView(_:)로 파란색 배경색 뷰를 arrangedSubviews 배열에서 제거했다.
화면에서도 파란색 배경색 뷰가 사라진거 같다.
좀 더 자세하게 알아볼까?

화면에는 초록색 배경색 뷰만 그려졌으니 View hierarchy에는 StackView에 하나의 view만 들어 있어야하는데 두개가 들어가 있다.
즉, removeArrangedSubview(_:)를 사용하면 arrangedSubviews 배열에서 뷰를 제거할 수는 있지만 View hierarchy에서는 제거를 하지 못한다.


그렇다면 어떻게 뷰를 제거해야 View hierarchy에서도 제거할 수 있을까?

이에 대한 해답은 애플 공식 문서에서 찾을 수 있었다.

removeArrangedSubview(_:) 메서드를 호출한 후 뷰가 화면에 나타나지 않도록하려면 뷰의 removeFromSuperview() 메서드를 호출하여 뷰를 명시적으로 제거하거나 뷰의 isHidden속성을 true로 설정한다.

removeArrangedSubview(_:) 메서드를 호출해 arrangedSubviews() 배열에서 뷰를 제거했다.
제거하려는 뷰에서 removeFromSuperview() 메서드를 호출해 View hierarchy에서도 제거했다.


마무리

이전에는 의례 이렇게 써야지 되는구나 했었는데 오늘 정리를 하면서 왜 이렇게 써야되는지 알게되었다.
역시... 공부를 해야...ㅋㅋㅋ
그럼 이만👋

1개의 댓글

comment-user-thumbnail
2022년 6월 1일

라자냐, 많은 도움이 됐습니다. 감사해요! ☺️

답글 달기