swift로 로그인 & 회원가입 페이지 만들기
👩🏻🏫 이번주 학습 목표 👨🏻🏫
- Autolayout으로 실제 프로덕트 레이아웃을 짜는 방법에 대해 이해한다.
- 주요 UI컴포넌트 (UIImageView, UITextField ..) 의 속성과 사용 방법에 대해 이해한다.
- IBOutlet, IBAction에 대해 이해한다.
- Gesture에 대해 이해한다.
- layer, cornerRadius 속성에 대해 이해하고 활용할 수 있다.
- UINavigationController에 대해 이해한다.
- UINavigationController를 통해 화면 전환 및 데이터 전달하는 방법에 대해 이해한다.
☀️KEY WORD☀️
1. UIImageView.contentMode
- UIImageView: 단일 이미지 또는 일련의 애니메이션 이미지를 인터페이스에 표시하는 개체
Declaration
@MainActor class UIImageView : UIView
- UIImageView.contentMode: 이미지 뷰의 크기가 조정될 때, 이미지가 어떻게 보일지 조정하는 옵션
Declaration
enum ContentMode : Int, @unchecked Sendable
- Scale To Fill (default)
- UIImageView 사이즈의 크기에 맞게 이미지를 조정하는 옵션
- 비율이 깨질 수 있음
- 비율을 깨며너 화면을 채우기 때문에 이미지가 잘릴 수 있음
- Aspect Fit
- 이미지의 가로 세로 비율을 유지하여 UIImageView 크기에 맞게 이미지 크기를 조정하는 옵션
- 뷰 경계의 나머지 영역은 투명
- 이미지가 잘리지 않음
- Aspect Fill
- 보기 크기를 채우기 위해 콘텐츠 크기를 조정하는 옵션
- 뷰의 경계를 채우기 위해 콘텐츠의 일부가 잘릴 수 있음
- 비율이 유지 되면서 화면을 채움
- 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) 위에 위치하고 있다.
- UIView는 하나의 CALayer(Root)만 가지고 있다.
4. IBAction/IBOutlet
UI와 코드를 연결하는 Outlet과 Action
@IBOutlet
과@IBAction
은 스토리보드의 UI와 코드를 연결하는 역할을 한다.- IB 는 Interface Builder의 약자이다.
- @는 어노테이션 이라고 하며, 프로퍼티(변수 혹은 메소드)의 성격을 알려주는 역할을 한다. (여기에서는 객체가 인터페이스 빌더와 관련있음을 의미한다)
- IBAction
- 컨트롤에서 발생한 이벤트를 코드를 통해서 처리할 때 사용한다.
- 즉, 버튼등이 클릭되는 '이벤트' 가 발생했을때 어떤 동작을 할 것인지 정의하는 메소드라고 생각하면 된다.
Ctrl 드레그앤 드롭
or마우스 오른쪽 클릭 드레그앤 드롭
@IBAction func btn(_ sender: Any) {
}
- 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)
- Segue 사용
- 스토리보드 상에서 viewcontroller들을 연결시키는 방법
- 전환흐름을 시각적으로 알 수 있어서 눈으로 보기에 편함
- 별다른 코드 없이 간단하게 화면전환을 할 수 있지만 직접 드래그 앤 드로으로 연결해야해서 불편할 수 있음
@IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
self.performSegue(withIdentifier: "[연결한 segue의 identifier]", sender: self)
}
- 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)
}
- 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해서 앞으로 돌아감
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가 보여지거나, 이동간 애니메이션을 설정하기 위해 사용합니다.
- The views of a navigation controller -
UINavigationController
의 뷰 구조
8. 화면 생명 주기
- UIViewController의 생명주기
- 뷰의 상태 감지 매소드
- viewDidLoad()
- 뷰 계층이 메모리에 로드된 직후 호출되는 메서드
- 1회 호출되며 메모리 경고로 뷰가 사라지지 않는 이상 다시 호출되지 않음.
- 주로 뷰의 초기화 작업을 담당합니다.
- viewWillAppear
- 뷰가 뷰 계층에 추가되고 화면이 표시되기 직전에 호출되는 메서드
- 화면이 새로 올라올 때마다 수행
- 그때마다 수행해야 할 작업을 담당하기에 유용
- viewDidAppear
- 뷰가 뷰 계층에 추가되어 화면이 표시되면 호출되는 메서드
- 뷰를 보여줄 때 필요한 추가적인 작업을 할때 유용
- viewWillDisappear
- 뷰가 뷰 계층에서 사라지기 직전에 호출되는 메서드
- 뷰를 생성하고나서 했던 행동들을 되돌리는 작업할 때
- 작성 또는 선택된 정보들을 삭제되기 전에 저장해두는 작업할 때
- viewDidDisappear
- 뷰가 뷰 계층에서 사라진 후 호출되는 메서드
- 뷰를 숨기는 것과 관련된 추가적인 작업을 할때
9. StackView
열 또는 행에 뷰 집합을 배치하기 위한 간소화된 인터페이스
Spacing, Alignment, Distribution를 사용해서 형태를 잡아 줄 수 있다.
- Spacing
- Spacing은 스택뷰 안의 뷰 간 간격을 설정
- Alignment
-
View들을 스택뷰를 이용해 정렬할 때, Alignment를 이용해서 좀 더 세부적인 설정이 가능
-
Horizontal
- Fill: 세로 사이즈 만큼 뷰 채우기
- Top: 위쪽으로 정렬
- center: 가운데 정렬
- bottom: 밑으로 정렬
-
Vertical
- Fill: 가로 사이즈 만큼 뷰 채우기
- Leading: 왼쪽으로 정렬
- center: 가운데 정렬
- Trailing: 오른쪽으로 정렬
- 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로 만든거 같다.
Author And Source
이 문제에 관하여(swift로 로그인 & 회원가입 페이지 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yooyeri/swift로-로그인-회원가입-페이지-만들기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)