swift로 로그인 & 회원가입 페이지 만들기

👩🏻‍🏫 이번주 학습 목표 👨🏻‍🏫

  1. Autolayout으로 실제 프로덕트 레이아웃을 짜는 방법에 대해 이해한다.
  2. 주요 UI컴포넌트 (UIImageView, UITextField ..) 의 속성과 사용 방법에 대해 이해한다.
  3. IBOutlet, IBAction에 대해 이해한다.
  4. Gesture에 대해 이해한다.
  5. layer, cornerRadius 속성에 대해 이해하고 활용할 수 있다.
  6. UINavigationController에 대해 이해한다.
  7. UINavigationController를 통해 화면 전환 및 데이터 전달하는 방법에 대해 이해한다.

☀️KEY WORD☀️

1. UIImageView.contentMode

  • UIImageView: 단일 이미지 또는 일련의 애니메이션 이미지를 인터페이스에 표시하는 개체

Declaration

 @MainActor class UIImageView : UIView
  • UIImageView.contentMode: 이미지 뷰의 크기가 조정될 때, 이미지가 어떻게 보일지 조정하는 옵션

Declaration

 enum ContentMode : Int, @unchecked Sendable
  1. Scale To Fill (default)
  • UIImageView 사이즈의 크기에 맞게 이미지를 조정하는 옵션
  • 비율이 깨질 수 있음
  • 비율을 깨며너 화면을 채우기 때문에 이미지가 잘릴 수 있음

  1. Aspect Fit
  • 이미지의 가로 세로 비율을 유지하여 UIImageView 크기에 맞게 이미지 크기를 조정하는 옵션
  • 뷰 경계의 나머지 영역은 투명
  • 이미지가 잘리지 않음

  1. Aspect Fill
  • 보기 크기를 채우기 위해 콘텐츠 크기를 조정하는 옵션
  • 뷰의 경계를 채우기 위해 콘텐츠의 일부가 잘릴 수 있음
  • 비율이 유지 되면서 화면을 채움

  1. Redraw
  • setNeedsDisplay() 메서드를 호출하여 경계가 변경 될 때 뷰를 다시 표시하는 옵션

2. textField.placeholder

  • textField: 인터페이스에 편집 가능한 텍스트영역을 표시하는 오브젝트

Declaration

  @MainActor class UITextField : UIControl
  • textField.placeholder: 텍스트필드에 대해 설정 가능한 Atribute 중 하나
    -> 텍스트 필드에 다른 텍스트가 없을 때 표시되는 문자열, 기본 값은 nil값이며 시스템 정의 색상을 사용 함
    Declaration
  var placeholder: String? { get set }

3. layer

  • layer를 이해하기 위해서는 UIKit이 만들어진 과정을 알아야 함.

-> ios 앱을 사용할 때는 화면이 끊기지 않도록 초당 60 프레임의 속도를 유지해야하는데, 이를 유지하기 위해 GPU에서 직접 실행되는 OpenGL이 생겼다. OpenGL은 그래픽 하드웨어에 가장 빠르게 접근할 수 있다는 점이 가장 큰 장점이지만, 단순한 작업에도 코드가 매우 방대해진다.
따라서 OpenGL보다 더 적은 코드로 그래픽을 구현할 수 있는 Core Graphics라는 것을 만들게 된다. (CGColor, CGRect...)
근데 이 Core Graphics도 약간 Low Level(컴퓨터가 이해하기 쉬운 언어, 기계어,어셈블리어) 작업이라, 더욱 간단하게 사용하도록 만들자해서 Core Animation를 만들었다.
Core Animation에는 그래픽에 접근하는 많은 고급 기능이 들어있는데, 애플은 또 "근데 앱 만드는데 이렇게 고급 기능이 다 필요함? 아닌 것 같은데?"라고 생각해 고급기능을 버렸다. 그래서 Core Animation을 또 간단하게 만들어버린 것이 바로 UIKit!

따라서 우린 UIKit을 통해 최고 High Level(사람이 이해하기 쉽게 작성된 프로그래밍 언어)에서 그래픽에 접근을 할 수 있던 것!
이 UIKit에 단점이라고 한다면 단순화 시켜 사용하기는 좋을 수 있으나, Low Level에 있는 OpenGL이나 Core Graphics 보다는 적은(제한된) 기능을 제공할 수 밖에 없다.

-> UIView는 레이아웃, 터치 이벤트 등 많은 작업을 처리하긴 하지만 사실은 뷰 위에 컨텐츠나 애니메이션을 그리는 행위는 직접 하지 않는다고 보면 된다.

-> UIView는 직접 화면에 그리는 시각적 행위를 Core Animation에게 위임하는데 그게 (CA)layout이다.

  • UIView에서 CALayer의 구성
    • UIView는 하나의 CALayer(Root)만 가지고 있다.
      CALayer(Root)는 SubLayer를 여러 개 둘 수 있다.
      UIView의 SubView는 UIView의 CALayer(Root) 위에 위치하고 있다.

4. IBAction/IBOutlet

UI와 코드를 연결하는 Outlet과 Action

  • @IBOutlet@IBAction은 스토리보드의 UI와 코드를 연결하는 역할을 한다.
  • IB 는 Interface Builder의 약자이다.
  • @는 어노테이션 이라고 하며, 프로퍼티(변수 혹은 메소드)의 성격을 알려주는 역할을 한다. (여기에서는 객체가 인터페이스 빌더와 관련있음을 의미한다)
  1. IBAction
  • 컨트롤에서 발생한 이벤트를 코드를 통해서 처리할 때 사용한다.
  • 즉, 버튼등이 클릭되는 '이벤트' 가 발생했을때 어떤 동작을 할 것인지 정의하는 메소드라고 생각하면 된다.
  • Ctrl 드레그앤 드롭 or 마우스 오른쪽 클릭 드레그앤 드롭
  @IBAction func btn(_ sender: Any) {
    }
  1. IBOutlet
  • 컨트롤러의 header file에 선언된 객체를 인터페이스 빌더가 인식하도록 연결 하는것.
  • 코드를 통해서 스토리보드의 UI에 접근할 때 사용한다.
  • UI에 접근하기 위한 속성이라고 생각하면 된다.
  • Ctrl 드레그앤 드롭 or 마우스 오른쪽 클릭 드레그앤 드롭
  @IBOutlet weak var label: UILabel!

5. Gesture

UIGestureRecognizer - 위 클래스는 특정 제스처 인식기에 대한 동작을 정의

  • UIGestureRecognizer Sub-Class

    • UITapGestureRecognizer : 싱글탭 또는 멀티탭 제스처
    • UIPinchGestureRecognizer : 핀치(Pinch) 제스처
    • UIRotationGestureRecognizer : 회전 제스처
    • UISwipeGestureRecognizer : 스와이프(swipe) 제스처
    • UIPanGestureRecognizer : 드래그(drag) 제스처
    • UIScreenEdgePanGestureRecognizer : 화면 가장자리 드래그 제스처
    • UILongPressGestureRecognizer : 롱프레스(long-press) 제스처
  • iOS의 Standard Gesture

    • Tap : 컨트롤을 활성화하거나 항목을 선택합니다.
    • Drag : 아이템을 좌우 또는 화면으로 드래그할 수 있습니다.
    • Flick : 빠르게 스크롤하거나 화면을 넘길 수 있습니다.
    • Swipe : 이전 화면으로 돌아가거나 테이블 뷰에서 숨겨진 삭제 버튼을 표시할 수 있습니다.
    • Double tap : 이미지 또는 콘텐츠를 확대하거나 다시 축소합니다.
    • Pinch : 이미지를 세밀하게 확대하거나 다시 축소할 수 있습니다.
    • Touch and hold : 편집 가능한 텍스트 또는 선택 가능한 텍스트에서 수행될 경우 커서 지정을 위한 확대보기가 표시됩니다. 컬렉션 뷰의 경우 항목을 재배치할 수 있는 모드로 진입합니다.
    • Shake : 실행 취소 또는 다시 실행 얼럿을 띄웁니다.

→ 제스처 인식기를 사용하기 위해서 Target-Action 연결을 설정한 후 UIView의 메서드인 addGestureRecognizer(_:) 메서드를 통해 뷰에 연결해야 한다.

@IBAction func myActionMethod()
@IBAction func myActionMethod(_ sender: UIGestureRecognizer)

→ 제스처가 인식되면 해당 제스처 이벤트에 연결된 타깃에 액션 메시지가 전달된다. 호출되는 액션메서드는 아래의 메서드 구현 형식 중 하나와 같아야 한다.

  • UIGestureRecognizer의 주요 메서드

init(target: Any?, action: Selector?) : 제스처 인식기를 타깃-액션의 연결을 통해 초기화 합니다.
func location(in: UIView?) -> CGPoint : 제스처가 발생한 좌표를 반환합니다.
func addTarget(Any, action: Selector) : 제스처 인식기 객체에 타깃과 액션을 추가합니다.
func removeTarget(Any?, action: Selector?) : 제스처 인식기 객체로부터 타깃과 액션을 제거합니다.
func require(toFail: UIGestureRecognizer) : 여러 개의 제스처 인식기를 가지고 있을 때, 제스처 인식기 사이의 의존성을 설정한다.

  • UIGestureRecognizer의 주요 프로퍼티

var state: UIGestureRecognizerState : 현재 제스처 인식기의 상태를 나타냅니다.
var view: UIView? : 제스처 인식기가 연결된 뷰입니다.
var isEnabled: Bool : 제스처 인식기가 사용 가능한 상태인지를 나타냅니다.
var cancelsTouchInView : 제스처가 인식되었을 때 터치 이벤트가 뷰로 전달되는 여부에 영향을 미칩니다.
이 프로퍼티가 true(기본값)이고 제스처 인식기가 제스처를 인식했다면, 해당 제스처의 터치는 뷰로 전달되지 않습니다. 이전에 전달된 터치들은touchesCancelled(_:with:) 메시지를 통해 취소됩니다. 제스처 인식기가 제스처를 인식 못하거나 이 프로퍼티의 값이 false라면 뷰가 모든 터치를 전달받게 됩니다.
var delaysTouchesBegan : began 단계에서 제스처 인식기가 추가된 뷰에 터치의 전달 지연 여부를 결정합니다.
var delaysTouchesEnded : end 단계에서 제스처 인식기가 추가된 뷰에 터치의 전달 지연 여부를 결정합니다.

6. 화면 전환

swift의 화면전환방법은 크게 3가지

Segue 사용 : Storyboard
Modal을 이용하여 다른 ViewController 호출 : Present
NavigationController을 사용하여 화면전환 : Push (=Show)

  1. Segue 사용
  • 스토리보드 상에서 viewcontroller들을 연결시키는 방법
  • 전환흐름을 시각적으로 알 수 있어서 눈으로 보기에 편함
  • 별다른 코드 없이 간단하게 화면전환을 할 수 있지만 직접 드래그 앤 드로으로 연결해야해서 불편할 수 있음
 @IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
        self.performSegue(withIdentifier: "[연결한 segue의 identifier]", sender: self)
    }
  1. Modal을 이용하여 present
  • 새로운 viewcontroller를 하나 만든 다음 스토리보드의 ID 정해주기
@IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
        let newVC = self.storyboard?.instantiateViewController(identifier: "[연결하고 싶은 화면 스토리보드의 ID]")
        //modal에서는 ransitionStyle과 resentationStyle를 따로 지정을 해줄 수 있음 -> present를 이용해서 화면 전환
        newVC?.modalTransitionStyle = .coverVertical
        newVC?.modalPresentationStyle = .automatic
        self.present(newVC!, animated: true, completion: nil)
    }
  1. NavigationController을 사용하여 push
  • NavigationController을 사용하여 Push하기, 여기서 push는 show의 개념
  • 새로운 뷰를 만들고 스토리보드의 ID 정해주기
@IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
        let pushVC = self.storyboard?.instantiateViewController(withIdentifier: "[연결하고 싶은 화면]")
        self.navigationController?.pushViewController(pushVC!, animated: true)
    }

-> 2번 방식이랑 비슷하지만 pushViewController로 화면을 push 한다.

7. UINavigationController

계층구조로 구성된 content를 순차적으로 보여주는 container view controller

  • stack 구조로 구현되어 있다 - navigation stack
  • 계층 구조 탐색으로 앱 content 를 보여주기에 적절하다
  • 한번에 한 child view controller 의 content 만 보여진다.
    ex. Setting, Clock
  • pop/push method를 사용하여 보여지는 child view controller 를 변경한다.

    -> push해서 하위 뷰로 이동하고 pop해서 앞으로 돌아감
  1. UINavigationController가 가지고 있는 요소

  • viewControllers: navigation controller 는 여러개의 view controller 를 관리할 수 있는 container view controller 이기 때문에 해당 navigation stack 에 쌓인 view controller 들을 배열 형태로 가지고 있습니다. 해당 배열은 push, pop 형태로 관리됩니다.
  • navigationBar: 앱을 사용하다 보면 상단에 타이틀, 뒤로가기, 설정등 특정 영역에 UI 요소들이 배치된 경우를 볼 수 있는데, 해당 영역을 navigationBar라고 합니다. 해당 navigationBar 를 통해 굳이 UI를 추가하거나 세팅할 필요없이 해당 view controller 를 위한 UI를 설정할 수 있습니다.
  • toolbar: 사파리 앱에서 흔히 아래쪽에 공유하기나 여러 버튼들이 모여있는 것을 볼 수 있는데, 이를 toolbar라고 합니다. 기본적으로 navigation controller 에서는 숨김처리 되어 있지만, 숨김을 해제하고 해당 영역을 설정할 수 있습니다.
  • delegate: UITableViewDelegate 처럼 UINavigationController 에도 특정 Event에서 사용할 수 있는 delegate가 선언되어 있습니다. 보통 특정 view controller가 보여지거나, 이동간 애니메이션을 설정하기 위해 사용합니다.
  1. The views of a navigation controller - UINavigationController의 뷰 구조

8. 화면 생명 주기

  1. UIViewController의 생명주기

  1. 뷰의 상태 감지 매소드
  • viewDidLoad()
    • 뷰 계층이 메모리에 로드된 직후 호출되는 메서드
    • 1회 호출되며 메모리 경고로 뷰가 사라지지 않는 이상 다시 호출되지 않음.
    • 주로 뷰의 초기화 작업을 담당합니다.
  • viewWillAppear
    • 뷰가 뷰 계층에 추가되고 화면이 표시되기 직전에 호출되는 메서드
    • 화면이 새로 올라올 때마다 수행
    • 그때마다 수행해야 할 작업을 담당하기에 유용
  • viewDidAppear
    • 뷰가 뷰 계층에 추가되어 화면이 표시되면 호출되는 메서드
    • 뷰를 보여줄 때 필요한 추가적인 작업을 할때 유용
  • viewWillDisappear
    • 뷰가 뷰 계층에서 사라지기 직전에 호출되는 메서드
    • 뷰를 생성하고나서 했던 행동들을 되돌리는 작업할 때
    • 작성 또는 선택된 정보들을 삭제되기 전에 저장해두는 작업할 때
  • viewDidDisappear
    • 뷰가 뷰 계층에서 사라진 후 호출되는 메서드
    • 뷰를 숨기는 것과 관련된 추가적인 작업을 할때

9. StackView

열 또는 행에 뷰 집합을 배치하기 위한 간소화된 인터페이스

Spacing, Alignment, Distribution를 사용해서 형태를 잡아 줄 수 있다.

  1. Spacing
  • Spacing은 스택뷰 안의 뷰 간 간격을 설정
  1. Alignment
  • View들을 스택뷰를 이용해 정렬할 때, Alignment를 이용해서 좀 더 세부적인 설정이 가능

  • Horizontal

    • Fill: 세로 사이즈 만큼 뷰 채우기
    • Top: 위쪽으로 정렬
    • center: 가운데 정렬
    • bottom: 밑으로 정렬
  • Vertical

    • Fill: 가로 사이즈 만큼 뷰 채우기
    • Leading: 왼쪽으로 정렬
    • center: 가운데 정렬
    • Trailing: 오른쪽으로 정렬
  1. Distribution
  • 스택 뷰 안의 뷰들의 관계를 나타낼 때 사용

  • fill: 설정한 크기에 맞게 뷰 채우기, Priority는 알아서 설정해주어야 함

  • Fill Equally: 모든 뷰의 크기를 같게 맞춰 줌

  • Equal Spacing: 모든 뷰의 간격을 동일하게 설정

  • Equal Centering: 컨텐츠의 가운데를 기준으로 간격을 맞춤

  • Fill Proportionally: 컨텐츠의 크기가 크면 여백이 커지고 컨텐츠의 크기가 작으면 여백의 작아짐 -> 비율적인 개념

💭생각해 보기💭

❔contentMode가 있는 컴포넌트는 뭐가 있을까요?

Hint. ContentMode는 컴포넌트를 구성하는 image를 보여주는 방식입니다.

-> UIImeageview, UIButton, UIView

❔특정 컴포넌트를 layer를 사용해서 꾸며보세요

-> UIView를 꾸며서 신호등 만들어보기

❔UIButton, UITextField에만 존재하는 IBAction이 존재합니다. 어떤 것들이 있나요?

-> ?

❔Control키를 누르고 swift파일로 드래그 앤 드랍했더니 자동으로 IBOutlet이 생겼어요! 반대로는 불가능할까요? (swift 파일에 코드를 먼저 쓴다면?)

-> 불가능하다

❔IBAction이 아니더라도 다른 컴포넌트들에게 Gesture를 통한 Event를 줄 수 있어요! 어떻게 하는 걸까요?

-> UITouch, UIEvent사용하기

❔화면의 전환에도 애니메이션을 선택할 수 있다?! 다음 화면의 보여주는 방식도 선택할 수 있다?!

Hint. OOOOViewController().~~~~~style

->

@IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
        let newVC = self.storyboard?.instantiateViewController(identifier: "[연결하고 싶은 화면 스토리보드의 ID]")
        //modal에서는 ransitionStyle과 resentationStyle를 따로 지정을 해줄 수 있음 -> present를 이용해서 화면 전환
        newVC?.modalTransitionStyle = .coverVertical
        newVC?.modalPresentationStyle = .automatic
        self.present(newVC!, animated: true, completion: nil)
    }

❔화면 전환에서 FullScreen과 FormSheet의 차이는 뭘까요?

-> FullScreen 은 화면을 모두 덮는 반면
PageSheet, FormSheet 는 dimming view 를 이용하여 Presenting VC 의 컨텐츠가 표시

❔카카오톡 친구 뷰는 StackView로 만든 것일까요?(Y/N) 그 이유는요?

-> Y 친구 뷰 하나에 프로필, 이름, 노래를 배열하는 것은
StackView로 만든거 같다.

좋은 웹페이지 즐겨찾기