添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

stack.addArrangedSubview

이원희 · 2021년 1월 19일
2

📱 iOS

목록 보기
13 / 24
post-thumbnail

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

UIStackView

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

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

StackView 를 사용하면 오토레이아웃의 기능을 활용하여 기기의 방향, 화면 크기 및 사용 가능한 공간의 모든 변경 사항에 동적으로 적용할 수 있는 사용자 인터페이스를 만들 수 있다.
StackView arrangedSubviews 프로퍼티로 모든 view들의 레이아웃을 관리한다.
arrangedSubviews StackView 의 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 view arrangedSubviews 프로퍼티는 [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() 배열에서 뷰를 제거했다.