iyOmSd/Title: Swift

[Swift] 코드로만 AutoLayout 적용하기(Programmatically AutoLayout)

냄수 2019. 10. 23. 20:35
반응형

안녕하세요~~😄😄

스토리보드를 이용해서만 디자인을 하고, 오토레이아웃도 적용시켰었는데

이번에는 ❗️코드로만❗️만들거에요

 

험난한 여정이 느껴지네요 벌써...

 

오토레이아웃의 기본이라고도 할 수 있을 것 같아요

계산기 앱을 만들어 볼거에요!!

 

StackView와 Button을 이용할 예정입니다!

 

우선 결과 화면은 이렇게 생겼어요

항상 스토리보드만 이용하다가 막상 시작하려니 막막~ 하더라구요

 

우선 스텍뷰안에 버튼을 넣어야 할것 같아요!!

    func stackViewFactory(type: NSLayoutConstraint.Axis)->UIStackView{
        let row = UIStackView()
        row.axis = .horizontal  //스텍 방향
        row.alignment = .center  //정렬
        
        row.distribution = .equalSpacing  //공간분배
        row.spacing = space
    
        return row
    }

이런식으로 스텍뷰의 속성을 설정해주고

let row1 = stackViewFactory(type: .horizontal)
self.view.addSubview(row1)
row1.translatesAutoresizingMaskIntoConstraints = false
row1.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: space).isActive = true
row1.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -space).isActive = true
row1.heightAnchor.constraint(equalToConstant: self.width).isActive = true
row1.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -self.space-10).isActive = true

오토레이아웃을 적용하기전에

view에 해당 UI가 존재해야되요!!

addSubview를 하지않고 레이아웃을 잡으려한다면 에러를 만나볼 수 있어요

꼭!! 먼저 뷰를 추가를 하고 레이아웃을 설정하도록해요

 

leftAnchor

rightAnchor

heightAnchor

bottomAnchor

.

.

.

등등 많은데 이름에서 느껴지듯이

그동안 스토리보드에서 했던 오토레이아웃을 설정할수있는 변수입니다!!

 

translatesAutoresizingMaskIntoConstraints = false를 설정해주고

꼭 뒤에는 .isActive = true로 해야 해당 오토레이아웃이 적용됩니다.

 

 

이런식으로 스텍뷰들을 설정해주고

이제 스텍뷰안에 버튼을 넣어줘야겠죠??

 

	let calcul2 = ["1","2","3","-"]
	
    func buttonGenerate(titleSet: [String], stack: inout UIStackView){
        for text in titleSet{
            var color: UIColor
            if text == titleSet[3]{
                color = UIColor.orange
            }else{
                color = UIColor.darkGray
            }
            
            let bt = buttonFactory(title: text, color: color)
            stack.addArrangedSubview(bt)
            
            bt.translatesAutoresizingMaskIntoConstraints = false
            bt.heightAnchor.constraint(equalToConstant: width).isActive = true
            bt.widthAnchor.constraint(equalToConstant: width).isActive = true
            
            bt.addTarget(self, action: #selector(numButtonClick), for: .touchUpInside)
        }
    }
    
    
     buttonGenerate(titleSet: calcul2, stack: &row2)

이런식으로 버튼을 생성하고

스텍뷰에 넣고

오토레이아웃을 적용해 봤습니다

 

자세히 설명하자면....

계산기가총 4줄이기때문에

저는 스텍뷰4개를 사용했어요

그 스텍뷰에 들어갈 계산기 버튼의 글씨도 배열로 만들었구요 그러면 배열도 4개가되죠!

 

해당 행에 맞는 String배열과 스텍뷰를 buttonGenerate넘겨주면

해당 스텍뷰에 String배열순서대로 문자열을가진 버튼을 생성해서 스텍뷰에 넣어주고

오토레이아웃도 적용해주는 함수에요!!

 

 

 

 

버튼 한개당 크기를 지정 할때는 잘생각해야되요

오토레이아웃으로 지정해버리는것이라서

폰이작아진다면 짤릴지도 몰라요!!

그래서

 

버튼크기도 동적으로 적용되는 방안으로 했어요

한줄에 버튼이 4개가 꽉차게 들어가는 형식이고

버튼간격은 10씩 줄거에요

 

그렇다면 버튼크기를 w라고하면

4*w + 50 만큼을 차지하게 되겠죠??

 

이 크기를 알고 있으니까 잘생각해보면!!!

(갑자기 수학적...)

 

 

뷰의 가로길이 / 4 에 - 12.5

를 해준크기가 버튼 한개의 크기가 될거에요

 

이 크기로 버튼 4개를 만든다면

뷰가로길이 - 50 이라는 수치가 되고

여기서 50은 공백을 의미하게 되요

 

width = self.view.frame.width/4 - 12.5

 

 

또한 계산기를 보면 숫자가 10000000 이렇게 보이는것 보다

10,000,000 이렇게 보이는게 이쁘잖아요?? 보기도좋고

 

그작업을 해줄게요

 

extension Int{
    var comma: String {
        let format = NumberFormatter()
        format.numberStyle = .decimal
        format.groupingSize = 3
        format.groupingSeparator = ","
        
        return format.string(from: self as NSNumber) ?? ""
    }
}

DateFormatter를 써봣다면 비슷한 개념이에요

이작업도 Formatter를 이용해서 간단하게 처리할 수 있어요

 

numberStyle은 어떤 형식인지 정하는건데 여기서는 숫자니까 decimal로 하구요

groupingSize는 숫자 몇개단위로 할건지여서 1000단위마다 표시하니까 3개단위

groupingSeparator는 그단위마다 무엇을 첨가할건지를 정해줄거라 구분자 ,(콤마)를 추가할거에요

 

 

이렇게 코드만으로 간단하게 레이아웃을 만들어 봤어요

 

이렇게 코드로만 짜면 코드가 길어져서 난해해 보일수도 있지만

협업시 스토리보드상에서 에러가나서 확인하는데 고생하는 불상사는 안 일어날거에요

반응형