본문 바로가기

iOS

Swift - UIStackView

요즘에 autolayout에 대해서 공부하면서 UIStackView를 사용해 보기로 해서

사용하면서 알게된 점이랑 원리 그리고 간단한 사용방법에 대해서 알아보도록 할게요

처음엔 저도 좀 헤메기는 했지만 예제를 따라 해 보니깐 어느 정도 이해는 되더라고요

그렇게 어렵지는 않으니 천천히 읽어 보시면 될 것 같아요 :)

제가 참고한 자료는 아래쪽에 링크를 걸어둘 테니 보시면 될 것 같아요!!


 

먼저 애플 공식 문서에 나와있는 스택 뷰를 쓰면 좋은 점에 대해서 보겠습니다

"Stack views let you leverage the power of Auto Layout,

creating user interfaces that can dynamically adapt to the device’s orientation,

screen size, and any changes in the available space."

라고 애플 문서에 나와있는데 짧게 번역하자면

"스택 뷰는 네가 오토 레이아웃의 힘을 활용해서 디바이스의 스크린 사이즈나 모든 변화에 가능한 동적인 ui를 구성할 수 있다"

라고 볼 수 있습니다


제가 실제로 사용해본 결과 굉장히 만족스러웠습니다

복잡한 ui를 구성하는 데 있어서 일일이 하나씩 오토 레이아웃을 설정하면

복잡해지기도 하고 실제로 원하는 대로 안 나오는 경우가 많은데

스택 뷰를 사용하게 되면 제가 일일이 오토 레이아웃 설정을 해주지 않아도 최적의 상태의 ui를 구성해 주니 굉장히 편했습니다


말로만 설명하기에는 힘든 부분이 있어서 예제를 통해서 보도록 하겠습니다

환경 : xcode 11.6

출처 : https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/Art/simple_stack_2x.png

저희는 위의 사진처럼 구성할 것이고 1, 2, 3, 4의 constant는 0으로 만들어 주시면 됩니다

 

1. 프로젝트 파일을 생성하여 줍니다

 

Single View App을 선택한 다음 Next를 눌러준다
Product Name을 작성해준 다음 체크는 다 풀어 준 다음에 Next를 선택

 

2. StackView타입의 프로퍼티를 선언하여 줍니다

 

import UIKit

class ViewController: UIViewController {
    
    var stackView : UIStackView! //무조건 초기화 해줄것이기 때문에 강제 옵셔널을 해도 된다
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

 

3. StackView의 configuration을 만들어 줍니다

출처 : https://docs-assets.developer.apple.com/published/82128953f6/uistack_hero_2x_04e50947-5aa0-4403-825b-26ba4c1662bd.png

위의 사진은 axis가 수평을 기준으로 설명하고 있습니다

 

axis는 수직으로 할지 수평으로 할지 설정하는 부분입니다

수직이라면. vertical을 수평이라면. horizontal으로 설정해주시면 됩니다

 

alignment는 정렬 형태를 표시하는 것인데 case가 8개 정도 존재하는데 그중에서. fill만 보도록 하겠습니다

나머지 case들은 developer.apple.com/documentation/uikit/uistackview/alignment 이 링크에서 확인 바랍니다

정렬에 fill이라니 뭔가 좀 안 어울린다는 생각을 했었지만

fill은 자신이 사용할 수 있는 영역을 다 채우며 적절한 위치에 배정이 되게 됩니다

 

01
첫번째 이미지는 .fill 두번째 이미지는 .center를 사용한 모습이다

위의 두 개의 사진을 보시니깐 fill이 어떤 역할을 하는지 감이 조금 오시나요?

 

distribution은 말 그대로 분배하는 역할을 합니다 case에는 5개 정도 존재하는데 여기서는 fill만 보도록 하겠습니다

나머지 case들은 developer.apple.com/documentation/uikit/uistackview/distribution 이 링크에서 확인하시면 됩니다

fill은 axis를 기준으로 삼아서 할당된 영역 중에서 자신이 채울 수 있는 만큼 다 채울 수 있도록 만들어 줍니다

 

spacing은 뷰와 뷰사이의 간격을 일정하게 만들어주는 역할을 한다

 

func setStackView() {
        self.stackView = UIStackView()
        self.stackView.axis = .vertical
        self.stackView.alignment = .fill
        self.stackView.distribution = .fill
        self.stackView.spacing = 8
        self.stackView.translatesAutoresizingMaskIntoConstraints = false
}

Storyboard를 통하여 작업하시는 거면 translatesAutoresizeingMaskIntoConstraints를 작성해주지 않아도 됩니다

 

4. superview의 subview로 만들어 줍니다

func setStackView() {
  self.view.addSubview(self.stackView)
  self.stackView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 30).isActive = true
  self.stackView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
  self.view.bottomAnchor.constraint(equalTo: self.stackView.bottomAnchor).isActive = true
  self.view.trailingAnchor.constraint(equalTo: self.stackView.trailingAnchor).isActive = true
}

addSubView 밑에 부분에 작성된 코드는 auto layout을 생성해주는 부분인데 storyboard라면 작성 안 하셔도 됩니다

 

5. StackView를 구성할 클래스들을 초기화하여 생성해 줍니다

func setStackView() {
        
        
        let label = UILabel()
        label.text = "Ocean"
        
        let imageView = UIImageView()
        imageView.image = UIImage(named: "ocean")
        imageView.setContentHuggingPriority(UILayoutPriority(249), for: .vertical)
        imageView.setContentCompressionResistancePriority(UILayoutPriority(749), for: .vertical)
        
        let button = UIButton()
        button.setTitle("사진 바꾸기", for: .normal)
        button.setTitleColor(.systemBlue, for: .normal)
}

 

HuggingPriority와 CompressionResistancePriority가 어떻게 보면 StackView를 구성하는 데 있어서 중요한 역할을 한다고 생각합니다

이 두 개의 LayoutPriority가 존재하기에 사진같이 큰 사이즈들을 화면 안에 넣을 수 있도록 만들어 줍니다

 

01
첫번째 사진은 LayoutPriority를 적용한 모습이고 두번째는 적용하지 않은 모습이다

위의 사진을 보시면 아시겠지만 적용하지 않은 것은 사진이 자신의 원래 사이즈로 인해서 밑에 버튼이 반쯤 사라지는 것을 보실 수 있을 텐데

이제 저런 것을 방지해주기 위해서 사진의 우선순위를 다른 UILabel이나 UIButton에 비해 낮게 설정해 주는 것입니다

그러면 이제 사진의 크기는 나머지 2개의 사이즈에 의해서 자동으로 결정되게 됩니다

추가적으로 각각의 우선순위는 HuggingPriority는 250 CompressionResistancePriority는 750으로 생성 시 자동으로 설정된다

 

 

6. StackView에 addArrangedSubView 메서드를 통하여 추가해 줍니다

func setStackView() {

        self.stackView.addArrangedSubview(label)
        self.stackView.addArrangedSubview(imageView)
        self.stackView.addArrangedSubview(button)
}

코드 풀 버전은 아래쪽에 링크로 남겨둘 테니 필요하신 분은 보시면 될 것 같아요 ㅎ

 


지금까지 StackView에 대해서 간단하게 알아보았는데

사실상 너무 복잡하게 구성하지만 않는다면 이 정도만 알고 있어도 괜찮게 UI를 구성할 수 있습니다

 

늘 얘기하지만 읽어주셔서 감사하고 무언가를 배웠다면 더 감사드려요 ㅎㅎ

 

github.com/baek0318/iOS_Practice/blob/master/StackView_Practice/StackView_Practice/ViewController.swift

 

baek0318/iOS_Practice

iOS를 공부하면 작성한 코드. Contribute to baek0318/iOS_Practice development by creating an account on GitHub.

github.com

https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html#//apple_ref/doc/uid/TP40010853-CH11-SW1

 

Auto Layout Guide: Stack Views

 

developer.apple.com

'iOS' 카테고리의 다른 글

iOS12버전 호환되게 만들기  (0) 2020.07.16
SwiftUI - some 키워드에 대한 정리  (0) 2020.06.25
Swift - 달의 첫날과 마지막날 알아내기  (0) 2020.06.20