티스토리 뷰

TIL

[TIL] 2022 / 07 / 06

희철 2022. 7. 7. 01:36

AppDelegate & SceneDelegate

 

iOS13 이전엔 AppDelegate에서 프로세스(앱의 실행과 종료 등)와 UI의 생명주기(백그라운드 상태 로직 등)를 모두 관리했음.

 

하지만 iOS13부터 iPadOS의 멀티 윈도우 기능으로 인해 UI의 라이프사이클이 다양해짐.

 

"만약 멀티윈도우로 같은 앱을 여러 번 띄웠을 때, 하나만 종료한다면 그 앱은 액티브 상태인가?" 라는 의문을 갖게 됨.

-> SceneDelegate 등장

 

iOS13 이전의 구조

 

AppDelegate

  • Process LifeCycle
    • 앱의 시작
    • 앱의 종료
    • ...
  • UI LifeCycle
    • Entered Foreground
    • Became Active
    • ...

iOS13 이후의 구조

 

AppDelegate

  • Process LifeCycle
    • 앱의 시작
    • 앱의 종료

SceneDelegate

  • UI LifeCycle
    • Entered Foreground
    • Became Active

iOS13 이전엔 AppDelegate에서 UIWindow를 통해 뷰컨트롤러를 화면에 표시해주었지만, iOS13 이후엔 SceneDelegate에서 담당

 

AppDelegate의 함수

  •  didFinishLaunchingWithOptions
    -> 실행프로세스가 거의 끝나고 앱이 실행될 준비가 거의 되었음을 알려줌.
  • configurationForConnecting
    -> Scene을 만들 때 호출
  • didDiscardSceneSessions
    -> Scene을 닫을 때 호출

SceneDelegate의 함수

  • scene
    -> scene이 앱에 추가될 때 호출되는 함수. AppDelegate에서 configurationForConnecting함수가 호출되고 scene이 추가되면 
         scene 호출.
  • sceneDidDisconnect 
    -> scene이 active상태에서 inactive상태로 갈 때 호출됨.
  • sceneDidBecomeActive
    -> scene이 사용될 준비가 완료된 상태. Inactive에서 active로 갈 때도 호출됨.
  • sceneWillEnterForeground
    -> scene이 foreground로 전환될 때 호출됨. 처음 active상태가 될 때, background → foreground 두 가지 경우에 호출될 수 있음.
  • sceneDidEnterBackground
    -> foreground에서 background로 전환될 때 호출됨.

버전 대응

 

위의 내용에서 말했지만, iOS13부터 AppDelegate와 SceneDelegate로 나눠짐.

-> 13 이전 버전의 시뮬레이터에서 빌드하면 컴파일에러가 많이 남.

위에서 발생하는 컴파일에러들은 전부 버전때문에 발생하는 에러들임. 따라서 에러가 뜨는 부분에 @available을 통해 대응을 해주면됨.

위와 같이 오류가 생기는 scene과 관련된 부분에 @available(iOS 13.0, *)을 이용해 13.0 이상의 버전에서만 사용하도록 만들어주었음.

*은 13.0 이상을 나타냄. 즉, 13.0이후의 모든 버전에서는 사용한다는 얘기임.

 

@available은 함수, 클래스, 프로토콜을 플랫폼 별로 제한할 때 사용한다고 함. 즉, 위 사진처럼 함수에 대해 제한하고 싶다면 @available을 사용.

@unavailable을 이용해 버전을 제한할 수도 있음.

 

반면, 여러 플랫폼에서 버전에 따라 서로 다른 처리를 하기 위해서는 #available이 사용된다고 함. 이때 *는 필수

-> 따라서 if 또는 guard와 같이 사용

-> 아래처럼 쓰임.

if #available(iOS 13.0, *) {
          // iOS 13 이후 버전
 } else {
         // iOS 13이 아닌 다른 버전들.
 }

=> 아직 정확히 어떨 때 쓰이는지 감이 안와서 조금 더 봐야할듯.

 

Code Snippet

 

위의 SceneDelegate에선 @available(iOS 13.0, *)을 클래스 위에 한 번만 사용했음.

 

하지만 클래스 안에 여러 함수가 있고, 이 함수들 중 여러 가지에 대해 available코드를 작성해주어야 할 때 매번 작성하기 귀찮음.

 

이때 원하는 코드를 저장해놓고 불러와서 붙여넣을 수 있는 것이 Code Snippet.

 

즉, 자주 쓰이는 코드를 저장해놓아 필요할때 바로바로 불러올 수 있음.

 

자주 쓸 코드를 드래그하고 마우스 오른쪽을 눌러서 create code snippet을 누르면 생성할 수 있음.

커서를 storyboard 파일이 아닌 swift파일에 가져다놓고 +버튼을 누르면 됨. (오브젝트 라이브러리 버튼)

 

Dark Mode

 

iOS13부터 생겼음.

 

시스템을 다크모드로 설정하더라도 앱에서는 다크 모드로 동작하지 않게 할 수 있음(Light모드를 디폴트로)

 

UIColor를 보면 앞에 system이 붙은 색을 볼 수 있는데, 이것도 다크 모드와 관련된 것.

-> 따로 설정하지않아도 system이 붙은 컬러를 사용하면 시스템이 다크 모드일때 색이 다크모드에 대응하는 색으로 바뀜.

 

Color Set을 추가할 수 있는데, 이 때 Appearance를 이용해 다크 모드일때의 컬러를 직접 정할 수 있음.

 

Device Orientation

 

-> 기기의 방향을 나타냄

  • Portrait: 세로 (기본적인)
  • Upside Down: 뒤집어진 상태
  • Landscape Left: 왼쪽으로 돌아간 상태
  • Landscape Right: 오른쪽으로 돌아간 상태

방향을 고정시키기 위해선 general의 device orientation에서 체크만 하면 안 될 수도 있음.

-> build Settings에서 info.plist values에서 해당하는 플랫폼 칸에서 원하는 방향을 제외하고 - 하면 됨.

 

Debug View Hierarchy

 

-> 뷰의 계층 구조를 볼 수 있어서, 어디에서 문제가 생기는지 확인 가능.

 

UIWindow

 

UIWindow는 user interface에 배경을 제공하고, 중요한 이벤트 처리 행동을 제공하는 객체

 

UIWindow가 없다면 빌드 했을 때, 검은색 화면만 나옴.

 

액자라고 생각하면 됨. UIView를 사진이라고 생각.

-> Window는 직접적으로 보여지는 내용은 없지만, 앱의 View에 기본 컨테이너를 제공

 

텍스트필드를 이용할 때, 입력 후 키보드 내리기

 

뷰컨트롤러에서 connection inspector를 가보면 지우지 못하는 view가 보일 것임.

뷰컨트롤러를 생성하면 기본적으로 깔리는 상위 뷰를 의미하는듯.

 

아무튼 화면을 터치해서 키보드를 내려보기로 함.

위에 보이는 뷰에 tapGesture를 넣고, 이 제스쳐의 액션에서 view.endEditting(true)

 

______________________________________________________________________________________________________

 

TextField의 placeholder 색 변경

 

emailTextField.attributedPlaceholder = NSAttributedString(string: "이메일 주소 또는 전화번호", attributes: [NSAttributedString.Key.foregroundColor : UIColor.white])

위의 코드를 이용하여 placeholder의 색을 바꿔줌.

string에는 text, attributes의 foregroundColor에는 placeholder의 색을 쓰는 것 같음.

하지만 위 코드가 정확히 어떤 의미인지는 더 알아봐야 될 것 같음.

 

 

UISwitch

 

1. setOn을 이용해 스위치의 초기 상태 세팅

setOn을 true로 한 경우, 빌드했을 때 스위치의 초기 상태는 On

setOn을 false로 한 경우, 빌드했을 때 스위치의 초기 상태는 Off

 

2. off상태에서의 배경색 변경 

plusSwitch.backgroundColor = .gray
plusSwitch.layer.cornerRadius = plusSwitch.frame.height / 2

backgroundColor를 바꾸면, 뒤의 view의 색이 바뀌어 스위치를 벗어난 주변까지 색이 변함

-> cornerRadius를 이용하여 스위치의 모양만큼 둥글게 만듦.

 

3. 스위치의 상태를 이용하여 Label을 hidden시킴

 

isOn이라는 switch의 메서드를 이용해봄.

@IBAction func tapSwitch(_ sender: Any) {
        if plusSwitch.isOn {
            hiddenLabel.isHidden = false
        } else {
            hiddenLabel.isHidden = true
        }
    }

 

단락 평가를 이용한 조건 판단

 

단락 평가란 앞의 조건이 false라면 이후의 것들은 확인하지않고 넘어가는 것.

아래처럼 코드를 작성해봤는데 맞는지는 모르겠음. 제대로 구현은 됨.

@IBAction func tapSignUpBtn(_ sender: Any) {
        view.endEditing(true)
        if emailTextField.text == "" {
            print("이메일 또는 전화번호를 입력하세요.")
        } else {
            if pwTextField.text == "" {
                print("비밀번호를 입력하세요.")
            } else {
                if pwTextField.text!.count < 6 {
                    print("비밀번호가 너무 짧습니다.")
                } else {
                    if nameTextField.text == "" {
                        print("닉네임을 입력하세요.")
                    } else {
                        if locationTextField.text == "" {
                            print("위치를 입력하세요.")
                        } else {
                            print("회원가입이 완료되었습니다.")
                        }
                    }
                }
            }
        }
    }

'TIL' 카테고리의 다른 글

[TIL] 2022 / 07 / 09  (0) 2022.07.09
[TIL] 2022 /07 / 08  (0) 2022.07.08
[TIL] 2022 / 07 / 07  (0) 2022.07.07
[TIL] 2022 / 07 / 05  (0) 2022.07.05
[TIL] 2022 / 07 /04  (0) 2022.07.05
댓글
최근에 올라온 글
Total
Today
Yesterday