SnapKit, Then

Choong Won, Seo·2022년 5월 24일
0

mdoc

목록 보기
4/8
post-thumbnail

Today 5/21-5/24

StoryBoard → Code

  1. Storyboard 지우기
  2. Info.plist → Scene Configuration → StoryboardName 탭 아예 삭제
  3. SceneDelegate에서 rootViewController 설정
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene) // SceneDelegate의 프로퍼티에 설정해줌
let mainViewController = ViewController() // 맨 처음 보여줄 ViewController

window?.rootViewController = mainViewController
window?.makeKeyAndVisible()

info.plist에서 StoryboardName을 삭제해야하는 이유

AppDelegate의 @main 함수가 Info.plis에서 storyboard의 이름을 참고하여 값이 있다면 시작 viewController로 인스턴스화 하기 때문

[iOS][Swift] - 스토리보드 없이 코드로만 UI 구현하기 (SceneDelegate에서 window설정)

UI 그려보기

UILable

let test = UILabel()
view.backgroundColor = .white // 배경색
view.addSubview(test)
test.text = "text" // test를 위해서 출력할 라벨 
test.translatesAutoresizingMaskIntoConstraints = false
test.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
test.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

navigationController

guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let mainViewController = ViewController()
let navigationController = UINavigationController(rootViewController: mainViewController)

window?.rootViewController = navigationController
window?.makeKeyAndVisible()

로그인 여부에 따라 달라지는 rootViewController

guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let userHasLoggedIn: Bool = true
//Login 안헀을 때 VC
let startViewController = StartViewController()
//Login 했을 때 VC
let homeViewController = HomeViewController()

let startVC = userHasLoggedIn ? homeViewController : startViewController
window?.rootViewController = startVC
window?.makeKeyAndVisible()

[iOS]View의 형성과정(window, rootView, Main함수, Appdelegate)

Font

코드로 하니까 스토리보드 사용해도 똑같았던 것들도 생소하게 느껴져서 폰트 넣는 것도 조금 버벅였는데, 서체관리자에서 Finde로 폰트 찾을 때 폰트 그룹 선택하면 bold, regular ... 하나하나 넣지 않아도 한 번에 적용된다. 폰트 이름 찾고싶을 때에는

for family in UIFont.familyNames {
  print(family)
    
  for sub in UIFont.fontNames(forFamilyName: family) {
    print("====> \(sub)")
  }
}

로 설치된 모든 폰트와 패밀리를 출력할 수 있고, 원하는 하나만 찾을 때는

for sub in UIFont.fontNames(forFamilyName: "SF Pro") {
  print("====> \(sub)")
}

로 쉽게 출력할 수 있다.

폰트 넣을 때에는 Add Target 꼭 체크하자

info.plist - Fonts provided by application에 확장자까지 잘 추가하자

Then

보통 코드로 뷰를 그릴 때, 이런 식으로 클로져를 통해 생성하고 실행한다.

lazy var startButton: UIButton = {
    let button = UIButton()
    button.backgroundColor = Colors.Semantic.mdocBlue
    button.setTitle("시작하기", for: .normal)
    button.titleLabel?.font = UIFont(font: FontFamily.SFProText.regular, size: 16)
    button.titleLabel?.textColor = Colors.Layout.I0
    button.addTarget(self, action: #selector(didTabButton), for: .touchUpInside)
    return button
}()

하지만 이 방법은 한 element를 구성할 때마다 안에서 계속 지역변수를 만들어주고 return해줘야 해서 비효율적이라 생각하고 있었는데, Then 라이브러리를 사용하면 깔끔하고 간소화한 코드를 작성할 수 있었다!

lazy var startButton = UIButton().then {
    $0.backgroundColor = Colors.Semantic.mdocBlue
    $0.setTitle("시작하기", for: .normal)
    $0.titleLabel?.font = UIFont(font: FontFamily.SFProText.regular, size: 16)
    $0.titleLabel?.textColor = Colors.Layout.I0
    $0.addTarget(self, action: #selector(didTabButton), for: .touchUpInside)
}

SnapKit

Snapkit은 Then과 마찬가지로 코드를 간결하게 쓸 수 있도록 도와준다.

Then은 인스턴스를 만드는데에 도움을 준다면, Snapkit은 AutoLayout을 짤 때 도움을 준다.

mdocLogo.translatesAutoresizingMaskIntoConstraints = false
mdocLogo.heightAnchor.constraint(equalToConstant: 96).isActive = true
mdocLogo.widthAnchor.constraint(equalToConstant: 200).isActive = true
mdocLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
mdocLogo.topAnchor.constraint(equalTo: view.topAnchor, constant: 60*UIScreen.main.bounds.width/100).isActive = true

AutoLayout을 설정할 때 항상 이와 같이 작성을 하는데, 반복된 함수들이 너무 복잡하게 느껴진다.

mdocLogo.snp.makeConstraints { make in
    make.height.equalTo(96)
    make.width.equalTo(200)
    make.centerX.equalToSuperview()
    make.top.equalToSuperview().inset(60*screenSize.width/100)
}

이럴 떄 Snapkit을 활용해서 하나의 클로저로 AutoLayout들을 한 묶음으로 만들어줄 수 있어서 좋고, make같은 매개변수를 이용해서 너무나 간결하게 코드를 단축시킬 수 있다.

translatesAutoresizingMaskIntoConstraints = false?

내부에서 정의해줘서 반복되는 autorizingMask꺼두는 작업을 하지 않아도 된다.

offset & inset의 차이

offset은 항상 superview기준이라고 생각하면 된다. superview에서 오른쪽으면 +, 왼쪽이면 -의 값을 갖는다.

inset은 UIEdgeInsets와 같이 edge기준으로 안으로 얼마나 떨어져 있는지를 나타낸다.

box.snp.remakeConstraints { make in
    make.top.left.bottom.right.equalToSuperview().inset(50)
}

또한 이렇게 나타낼 수도 있고,

box.snp.makeConstraints { make in
      make.edges.equalToSuperview().inset(50)
  }

edges를 사용해서 이렇게 하나로 나타낼 수도 있다.

left & leading의 차이

leading, trailing의 경우, right-to-left의 문화권의 경우 화면이 flip되어 나타난다.

하지만, left & right는 모든 문화권에서 같은 의미를 가지므로 같은 ui를 그릴 수 있다.

Constraint의 변수화

@IBOutlet으로 Constraint를 변수화해서 사용하고 싶은 곳에서 값을 변경해 사용할 수 있는데, snapkit에서도 이같은 작업이 가능하다. uninstall로 초기화한 다음 updateOffset으로 값을 변경해줄 수 있다.

var topConstraint: Constraint? = nil

view.snp.makeConstraints { make in
    self.topConstraint = make.top.equalTo(superview).offset(padding.top)
}
self.topConstraint.uninstall()
self.topConstraint.updateOffest(5)

혹은 아예 updateConstraints를 사용해서 이렇게 가능하다.

box.snp.makeConstraints { maker in
    maker.top.bottom.left.right.equalToSuperview()
}

box.snp.updateConstraints { maker in
    maker.top.equalToSuperview().offset(100)
}

[SnapKit] 스냅킷 헷갈리는 것 정리 (inset vs offset / left vs leading / translatesAutoresizingMaskIntoConstraints)

TabBar

ios 15이상부터 TabBar에 있었던 divider(shadow)가 사라지고 default 또한 translucent가 되었다.

하지만 반대로 지금 쓰려는 디자인이 divider가 필요한 디자인이어서 새로 divider를 살려야 했다...

tabBar.layer.borderWidth = 1
tabBar.layer.borderColor = Colors.Layout.I20.cgColor

layer로 접근해서 border값을 바꾸어주면 되는 일이었는데 바꾸다가 cgColor와 UIColor의 차이점이 문득 궁금해졌다.

간단하게 말해서 cgGraphics에 속해있는 layer을 통해 접근할 수 있는 색상에 대하여는 cgColor, UIkit을 통한 윗단계의 UI수정에 대해서는 UIColor를 사용해야하는 것 같았다.

iOS ) CGColor와 UIColor의 차이

profile
UXUI Design Based IOS Developer

0개의 댓글