TIL

48일차 TIL _codebaseUI

h_luz 2024. 5. 3. 23:33

 

스탠다드 반 강의 (복습)
스파르타 코딩 클럽

 

우선 코드베이스로 구현하려면 프로젝트를 생성 후, 메인 스토리보드를 삭제하고,

info에서 StoryboardName 부분에 Main으로 설정되어 있는 것을 지우고,

 

SceneDelegate 파일에서 ViewController를 연결해 주는 작업이 필요하다

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: windowScene) //SceneDelegate의 프로퍼티에 설정( var window:UIWindow? )
    let mainViewController = ViewController() // 처음 보여줄 ViewController 인스턴스 생성
    
    window?.rootViewController = mainViewController //window.rootViewController에 생성한 ViewController 넣기
    window?.makeKeyAndVisible()

 

UIWindowScene

: 앱에 대한 하나 이상의 창을 관리하는 뷰

 

UIWindow

: 앱의 사용자 인터페이스에 대한 배경과 이벤트를 뷰에 전달하는 개체

    ㄴ windowScene : The scene object in which to display the window.

 

makeKeyAndVisible()

: 윈도우를 표시하고 키 윈도우로 만듦

  ( 현재 창을 표시하고 같은 수준 이하의 다른 모든 창 앞에 배치하는 편리한 방법)

 

* Exception NSException * "Invalid parameter not satisfying: [name length] > 0" 0x00006000024690b0

    ㄴ 실행했더니 이런 에러가 떠서 검색해 본 결과

     ㄴ info에서 Storyboard Name 행 자체를 삭제하면 해결된다고 한다 !

 

또 에러 떠서 검색해 봤더니 이것도 삭제해줘야 하는 것 같다..

 

* 스탠다드 반 강의 들으면서 하는 게 낫겠다 싶어서 ,, 스탠다드반 강의 다시 들어보려 했는데

아핳.. 그렇구나.. ㅜ

view.backgroundColor를 지정 안 해줘서 그런 거였다.. !

backgroundColor 설정해 주면 잘 나오는 것을 확인할 수 있음 !


UIComponent 초기화

import UIKit

class ViewController : UIViewController {

    let titleLabel = UILabel()
    let mytableView = UITableView()
    let addButton = UIButton()

    let button1 = UIButton()
    let button2 = UIButton()
    let button3 = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
}

IBOutlet처럼 UIComponent 초기화 과정이 필요하다

 

 

addSubView()

: View에 요소를 추가해 주는 작업 ! ( viewDidLoad에 해줌 )

    ㄴ 계층 구조가 만들어져 부모 - 자식 관계가 됨

    ㄴ 주어진 뷰를 현재 뷰의 하위 뷰로 추가하는 것 ("superView"에 대해 "addSubview"를 호출하면 그 뷰의 하위에 새로운 뷰 추가)

import UIKit

class ViewController : UIViewController {

	//생략

    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(titleLabel)
        view.addSubview(tableView)
        view.addSubview(addButton)

        view.addSubview(button1)
        view.addSubview(button2)
        view.addSubview(button3)
    }
    
}

* 요소가 많으면 길어지기 때문에 배열에 담아서 사용할 수 있음 !

[titleLabel,myTableView,addButton].forEach {
	view.addSubview($0)
}

* 순서가 중요 !

    ㄴ 배경 이미지 위에 버튼을 보여주고 싶은 경우, 이미지를 먼저 올려주는 식으로 순서를 잘 지켜줘야 한다

 

StackView 코드로 추가

stackView.addArrangedSubview(button1,button2,button3)
[button1,button2,button3].forEach {
    stackView.addArrangedSubView($0)
}

* 배열 사용

 

TableView 코드로 추가

: 스토리보드에서는 register에서 Nib 어쩌고를 사용했었는데 CellClass를 사용해 주면 된다!

myTableView.register(MyTableViewCell.self, forCellReuseIdentifier: MyTableViewCell.identifier)

 

Cell

기존에 xib에서 사용해 줬던 awakeFromNib 메서드는 이제 필요 없어지고, init 오버라이드를 해야 한다.

import UIKit

class MyTableViewCell : UITableViewCell {
    let static identifier = "MyTableViewCell" //identifier 미리 등록
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
       super.init(style: style, reuseIdentifier: reuseIdentifier)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:)has not been implemented")
    }
}

 

* cell에서는 view에 접근을 할 수 없다 -> contentView (뷰컨트롤러에 view. 역할)

import UIKit

class MyTableViewCell : UITableViewCell {
	
    let myLabel = UILabel()

    let static identifier = "MyTableViewCell" //identifier 미리 등록
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
       super.init(style: style, reuseIdentifier: reuseIdentifier)
       
       contentView.addSubview(myLabel)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:)has not been implemented")
    }
}

 

그냥 간단하게 레이블 추가해 보는 연습!

오토레이아웃 안 잡아주면 화면에 안 나옴,, ㅠㅠ

그래서 일단 아무렇게나 잡아줬는데 저건 중앙에 맞춰주는 오토레이아웃인 것 같다!


 

코드 정리하는 법

- 함수로 묶어서 viewDidLoad()에 추가해 주면 더 깔끔한 코드로 정리할 수 있다.

   ㄴ setupContraints() -> addSubView, 오토레이아웃을 모은 함수

   ㄴ configureUI() -> UI 요소들의 속성 모음 함수

* 이건 예시이고, 자신이 원하는 대로 메서드 정의할 수 있음

//addSubView, 오토레이아웃 모음 함수
func setupConstraints() {
    //addSubView
    [titleLabel,myTableView,addButton].forEach {
	    view.addSubview($0)
    }
    
    //오토레이아웃
    
}

//UI 요소들의 속성 모음 함수
func configureUI() {
    view.backgroundColor = .white
    titleLabel.text = "제목 레이블"
    titleLabel.backgroundColor = .green
    
    myTableView.register(MyTableViewCell.self, forCellReuseIdentifier: MyTableViewCell.identifier)
}

override viewDidLoad() {
    super.viewDidLoad()
    
    setupConstraints()
    configureUI()
}

 

BaseViewController

: 메서드 이름을 맞추는 것이 중요한데,, BaseViewController를 상속받아서 활용하면 굳!

import UIKit

class BaseViewController : UIVIewController {
    super.viewDidLoad()
    
    setupConstraints()
    configureUI()
}

func setupConstraints() {
	// 내용
}

func configureUI() {
    // 내용
}

이렇게 새로운 파일을 만들어서 함수와 함수를 사용하는 부분을 작성해 주고,  ViewController : BaseViewController 즉, BaseViewController를 상속받도록 해주면 ViewController에서 그냥 저 함수를 입력해 줄 필요도 없이 깔끔하게 사용할 수 있다.

import UIKit

class ViewController : BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        //setupConstraints()와 configureUI()를 안 적어줘도 됨 !
    }
    
    override func setupConstraints() {
        super.setupConstraints()
    }
    
    override func configureUI(){
        super.configureUI()
    }
}

 

* override 된 function은 super을 불러야 한다!

 


 

Constraints 잡아주기

1. translatesAutoresizingMaskIntoConstraints = false

    ㄴ 간단하게 기기에 맞춰서 크기 조절을 해주는 기능 (동적으로 크기와 위치를 조절하려면 false 상태로 두어야 한다)

    ㄴ 오토레이아웃을 설정해 주기 위해 끄는 것!

textLabel.translatesAutoresizingMaskIntoConstraints = false

 

2. anchor 연결

요소.어디 쪽에 Anchor을 줄 건지.constraint(equalTo:앞에 정한 Anchor에서 비교될 부분, constant:얼마큼 떨어지게 할 것인지).isActive = true

textLabel.topAnchor.constraint(equalTo:view.safeAreaLayoutGuide.topAnchor, constant:30).isActive = true

view.safeAreaLayoutGuide.topAnchor 은 SafeArea의 top 부분을 뜻함

즉, textLabel의 topAnchor가 SafeArea의 top에 걸렸다는 뜻인데, 30만큼 준다는 의미

 

* centerXAnchor, centerYAnchor : 센터 잡기

 

* trailingAnchor를 줄 때 주의할 점

뷰의 방향은 이런 식이라서 trailing을 잡을 때 +30을 주면 밖으로 빠져나간 30을 의미하게 됨. 따라서 안쪽에 여백을 주려면 -30을 줘야 한다.

 


 

실습

SafeArea에서 textLabel top이 30만큼 떨어져 있고, leading과 trailing은 양쪽으로 20씩, textLabel의 높이를 50으로 정해줘서 오토레이아웃을 맞춰주었다!

 

코드를 정리해 보자면

이런 식으로 할 수 있음! 실행해 보면 위 화면과 동일하게 잘 실행된다!

 

 

 

'TIL' 카테고리의 다른 글

52일차 TIL  (2) 2024.05.10
49일차 TIL  (4) 2024.05.07
46일차 TIL  (0) 2024.05.01
45일차 TIL  (0) 2024.04.30
44일차 TIL  (5) 2024.04.30