카테고리 없음

코드베이스로 스택뷰 만들기

bluewiper 2024. 7. 11. 10:55

과제 

이미지와 레이블이 포함된 스택을 세줄 쌓으시오

 

처음에 할 때는 스택이 한줄만 보였다. 

 

이런 저런 오류를 만나고서 위 사진처럼 나오게 수정한 코드이다. 

더보기
import UIKit

class ViewController: UIViewController {
    
    let label1 = UILabel()
    let label2 = UILabel()
    let label3 = UILabel()
    
    let imageView1 = UIImageView()
    let imageView2 = UIImageView()
    let imageView3 = UIImageView()
    
    
    let hStackView1 = UIStackView() // 이미지 + 레이블
    let hStackView2 = UIStackView() // 이미지 + 레이블 hStackView 1 세번 쌓기 성공하면 써보기
    let hStackView3 = UIStackView() // 이미지 + 레이블
    
    let vStackView = UIStackView() // 이미지 + 레이블이 포함된 세 줄의 hStackView
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .orange
        
        configureUI()
    }
    
    func configureUI() {
        
        //labe1 속성
        label1.text = "heart"
        label1.textColor = .black
        label1.font = .boldSystemFont(ofSize: 30)
        label1.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(label1)
        
        //label2 속성
        label2.text = "cake"
        label2.textColor = .black
        label2.font = .boldSystemFont(ofSize: 30)
        label2.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(label2)
        
        //label3 속성
        label3.text = "sunglasses"
        label3.textColor = .black
        label3.font = .boldSystemFont(ofSize: 30)
        label3.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(label3)
        
        //imageView1 속성
        imageView1.image = UIImage(named: "heart")
        imageView1.contentMode = .scaleAspectFill
        imageView1.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(imageView1)
        
        //imageView2 속성
        imageView2.image = UIImage(named: "cake")
        imageView2.contentMode = .scaleAspectFill
        imageView2.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(imageView2)
        
        //imageView3 속성
        imageView3.image = UIImage(named: "sunglasses")
        imageView3.contentMode = .scaleAspectFill
        imageView3.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(imageView3)
        
        //hStackView1 속성
        hStackView1.axis = .horizontal
        hStackView1.alignment = .center
        hStackView1.backgroundColor = .orange
        hStackView1.spacing = 40
        hStackView1.translatesAutoresizingMaskIntoConstraints = false
        hStackView1.addArrangedSubview(imageView1)
        hStackView1.addArrangedSubview(label1)
        
        view.addSubview(hStackView1)
        
        //hStackView2 속성
        hStackView2.axis = .horizontal
        hStackView2.alignment = .center
        hStackView2.backgroundColor = .orange
        hStackView2.spacing = 40
        hStackView2.translatesAutoresizingMaskIntoConstraints = false
        hStackView2.addArrangedSubview(imageView2)
        hStackView2.addArrangedSubview(label2)
        
        view.addSubview(hStackView2)
        
        //hStackView3 속성
        hStackView3.axis = .horizontal
        hStackView3.alignment = .center
        hStackView3.backgroundColor = .orange
        hStackView3.spacing = 40
        hStackView3.translatesAutoresizingMaskIntoConstraints = false
        hStackView3.addArrangedSubview(imageView3)
        hStackView3.addArrangedSubview(label3)
        
        view.addSubview(hStackView3)
        
        
        //vStackView 속성
        vStackView.axis = .vertical
        vStackView.alignment = .center
        vStackView.distribution = .fillEqually
        vStackView.backgroundColor = .orange
        vStackView.translatesAutoresizingMaskIntoConstraints = false
        
        vStackView.addArrangedSubview(hStackView1)
        vStackView.addArrangedSubview(hStackView2)
        vStackView.addArrangedSubview(hStackView3)
        
        view.addSubview(vStackView)
        
        
        NSLayoutConstraint.activate([
            imageView1.widthAnchor.constraint(equalToConstant: 40),
            imageView1.heightAnchor.constraint(equalToConstant: 40),
            imageView2.widthAnchor.constraint(equalToConstant: 40),
            imageView2.heightAnchor.constraint(equalToConstant: 40),
            imageView3.widthAnchor.constraint(equalToConstant: 40),
            imageView3.heightAnchor.constraint(equalToConstant: 40),
            vStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            vStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            vStackView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
        
    }
    
}

configureUI()에서는 구성에만 신경쓸 수 있도록 하고 싶어서 수정하는 단계에서 깨달은 사실

 

UIStackView에 addArrangedSubview를 사용하여 뷰를 추가하면 해당 뷰는 자동으로 UIStackView의 자식 뷰가 된다. 따라서 UIStackView를 view에 추가하는 것만으로도 포함된 모든 자식 뷰들이 화면에 표시되기 때문에 따로 view.addSubview를 안 해줘도 된다. 

 

수정 후

더보기
import UIKit

class ViewController: UIViewController {
    
    let label1: UILabel = {
        let label1 = UILabel()
        //labe1 속성
        label1.text = "heart"
        label1.textColor = .black
        label1.font = .boldSystemFont(ofSize: 30)
        label1.translatesAutoresizingMaskIntoConstraints = false
        return label1
    }()
    let label2: UILabel = {
        let label2 = UILabel()
        //label2 속성
        label2.text = "cake"
        label2.textColor = .black
        label2.font = .boldSystemFont(ofSize: 30)
        label2.translatesAutoresizingMaskIntoConstraints = false
        return label2
    }()
    let label3: UILabel = {
        let label3 = UILabel()
        //label3 속성
        label3.text = "sunglasses"
        label3.textColor = .black
        label3.font = .boldSystemFont(ofSize: 30)
        label3.translatesAutoresizingMaskIntoConstraints = false
        return label3
    }()
    
    let imageView1: UIImageView = {
        let imageView1 = UIImageView()
        //imageView1 속성
        imageView1.image = UIImage(named: "heart")
        imageView1.contentMode = .scaleAspectFill
        imageView1.translatesAutoresizingMaskIntoConstraints = false
        return imageView1
    }()
    let imageView2: UIImageView = {
        let imageView2 = UIImageView()
        //imageView2 속성
        imageView2.image = UIImage(named: "cake")
        imageView2.contentMode = .scaleAspectFill
        imageView2.translatesAutoresizingMaskIntoConstraints = false
        return imageView2
    }()
    let imageView3: UIImageView = {
        let imageView3 = UIImageView()
        //imageView3 속성
        imageView3.image = UIImage(named: "sunglasses")
        imageView3.contentMode = .scaleAspectFill
        imageView3.translatesAutoresizingMaskIntoConstraints = false
        return imageView3
    }()
    
    let hStackView1: UIStackView = { // horizontalStacKView(이미지 + 레이블)
        let hStackView1 = UIStackView()
        //hStackView1 속성
        hStackView1.axis = .horizontal
        hStackView1.alignment = .center
        hStackView1.backgroundColor = .orange
        hStackView1.spacing = 40
        hStackView1.translatesAutoresizingMaskIntoConstraints = false
        return hStackView1
    }()
    let hStackView2: UIStackView = { // horizontalStacKView(이미지 + 레이블)
        let hStackView2 = UIStackView()
        //hStackView3 속성
        hStackView2.axis = .horizontal
        hStackView2.alignment = .center
        hStackView2.backgroundColor = .orange
        hStackView2.spacing = 40
        hStackView2.translatesAutoresizingMaskIntoConstraints = false
        return hStackView2
    }()
    let hStackView3: UIStackView = { // horizontalStacKView(이미지 + 레이블)
        let hStackView3 = UIStackView()
        //hStackView3 속성
        hStackView3.axis = .horizontal
        hStackView3.alignment = .center
        hStackView3.backgroundColor = .orange
        hStackView3.spacing = 40
        hStackView3.translatesAutoresizingMaskIntoConstraints = false
        return hStackView3
    }()
    
    let vStackView: UIStackView = { // 이미지 + 레이블이 포함된 세 줄의 hStackView
        let vStackView = UIStackView()
        //vStackView 속성
        vStackView.axis = .vertical
        vStackView.alignment = .center
        vStackView.distribution = .fillEqually
        vStackView.backgroundColor = .orange
        vStackView.translatesAutoresizingMaskIntoConstraints = false
        return vStackView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .orange
        
        configureUI()
    }
    
    func configureUI() {
        
        //hStackView1 구성
        hStackView1.addArrangedSubview(imageView1)
        hStackView1.addArrangedSubview(label1)
        
        
        //hStackView2 구성
        hStackView2.addArrangedSubview(imageView2)
        hStackView2.addArrangedSubview(label2)
        

        //hStackView3 구성
        hStackView3.addArrangedSubview(imageView3)
        hStackView3.addArrangedSubview(label3)
        
        
        //vStackView 구성
        vStackView.addArrangedSubview(hStackView1)
        vStackView.addArrangedSubview(hStackView2)
        vStackView.addArrangedSubview(hStackView3)
        
        view.addSubview(vStackView)
        
        NSLayoutConstraint.activate([
            imageView1.widthAnchor.constraint(equalToConstant: 40),
            imageView1.heightAnchor.constraint(equalToConstant: 40),
            imageView2.widthAnchor.constraint(equalToConstant: 40),
            imageView2.heightAnchor.constraint(equalToConstant: 40),
            imageView3.widthAnchor.constraint(equalToConstant: 40),
            imageView3.heightAnchor.constraint(equalToConstant: 40),
            vStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            vStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            vStackView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
        
    }
    
}

해보고 싶은 것

 

View와 Controller 분리