[iOS] - 회원가입화면 설계 및 레이아웃의 이해

수킴·2022년 1월 20일
0

iOS 

목록 보기
4/7

회원가입 화면 설계

RxSwift를 사용한다면??

RxSwift는 동기적인 동작을 비동기적으로 변경할 때 사용하는 라이브러리인데 회원가입화면에서 어느 곳에 필요할 지, 그리고 사용한다면 어느 장점이 있을까? 🤔

  1. 비동기적으로 실행할 필요가 없는 곳에서 사용은 당장은 필요없지만 Rx로 구현한다면 확장성측면에서 화면에서 비동기적으로 실행하도록 변경된다면 쉽게 변경가능할 수 있는 장점이 있을 것 같다.
  2. 비동기처리에서 @escaping클로저를 사용하면 반환값이 없기 때문에 가독성 측면에서 좋지 않기 때문에 반환값을 받는 RxSwift를 사용하면 가독성측면이나 개발하는데 편리한 장점이 있을 것 같다.
  3. 아키텍처패턴을 MVVM으로 구현한다면 패턴 구조상 반환값을 받는 Rx로 구현하면 패턴구현이 좀 더 수월한 장점이 있을 것 같다.

회원가입 화면에서는 어떤 곳에서 사용하는 것이 좋을까?

  • 인증받기 버튼을 클릭하면 파이어베이스에서 인증을 받는 동안 모든 화면이 멈춰서 인증번호 유효시간타이머가 멈추게 되서 비동기처리를 해야할 것 같다.
  • 텍스트필드의 유효성을 검사할 때 서버와 통신하여 검사를 하거나, 실시간으로 잘못되었다고 표시를 해야하는 경우 사용자에게 알리도록 처리할 수 있을 것 같다. (비동기 처리를 하지않으면 유효성검사를 하는동안 화면이 멈추기때문에)

🤔  idToken → 닉네임 → 생년월일 → 이메일 → 성별 순으로 화면이동하면서 값을 계속 전달할 때 어떤방법으로 하는게 좋을지??

  1. 구조체를 만든 후 각각의 프로퍼티를 옵셔널타입으로 지정하고 구조체를 전달해가면서 값전달하기
    • 계속해서 화면마다 구조체프로퍼티를 만들어야 할 것 같다.
  2. UserDefault를 사용하여 저장한 후 사용하기
    • 보안측면에서 중요한 내용을 저장한다면 단점이 있을 것 같다 → 회원가입한 후 바로 삭제

iOS 레이아웃 이해

뷰의 레이아웃이나 컨텐츠를 다룰 때 실질적으로 뷰 업데이트가 일어날때를 잘못 알고 있을 때 에러가 발생할 수 있습니다. 뷰 업데이트에 대해 알기 위해서는 Main Run LoopUIView 를 자세히 알아야합니다.

Main Run Loop

어플리케이션이 실행되면 iOS의 UIApplication이 매인 스레드에서 main run loop를 실행시킵니다.

Main Run Loop 는 모든 사용자 입력 이벤트를 처리하고 적절한 응답을 발생시키는 것 입니다. 사용자와 상호작용은 이벤트큐에 추가합니다. Application객체는 이벤트큐에서 이벤트를 가져와 Application의 다른 객체에 전달합니다. 이런 입력이벤트를 해석하고 Application의 핵심 객체에서 해당 입력이벤트에 대한 해당하는 handler를 호출하여 런루프를 실행합니다. 이러한 핸들러는 개발자가 작성한 코드를 호출이되고 이 메서드가 반환되면 Main Run Loop 와 업데이트 주기가 시작됩니다. 업데이트주기는 레이아웃과 뷰다시그리기를 담당하고 있습니다.

  • 사용자 터치 → Operating system → 이벤트큐추가 → 이벤트를 가져와 Application객체가 이벤트를 전달 Core객체에서 해당하는 handler를 처리한 후 반환 → MainRunLoop와 업데이트 주기 발생(레이아웃 및 뷰다시그리기) → 화면에 표시

Update Cycle

  • updateCycle은 앱이 모든 이벤트처리코드를 실행을 마친 후에 컨트롤이 mainRunLoop로 반환되는 시점입니다. 이 시점에서 시스템이 layout , display , constraints 의 업데이트를 시작합니다.
  • 이벤트처리하는 과정에서 뷰를 변경시키기를 요청하면 업데이트주기에서 변경사항을 실행합니다. 사용자의상호작용과 레이아웃 업데이트 사이의 지연은 사용자가 알 수 없어야 합니다.
  • ios앱은 일반적으로 60fps을 애니메이션이되면 refreshCycle이 1초에 60번 그린다는 의미입니다. 따라서 사용-자는 상호작용하는 것과 컨텐츠 및 레이아웃업데이트를 보는 것의 지연을 알 지못합니다.
  • 하지만 이벤트가 처리되는 시점과 해당 뷰를 다시그리는 시점사이에 간격이 있기 때문에 특정시점에서 뷰를 업데이트를 하기원해도 뷰가 업데이트되지 않을 수 도 있습니다.(어느 뷰가 가장 최근의 컨텐츠나레이아웃에 의존하여 계산하는 경우) 이러한 문제를 해결하기위해 run loop와 업데이트주기, UIview메서드를 알아야합니다.

Layout

뷰의 레이아웃은 화면의 size와 position 참조합니다. 모든 뷰는 슈퍼뷰의 좌표계에서 존재하는 size, position를 정의하는 프레임이 있습니다. UIView는 뷰의 레이아웃이 변경되었음을 시스템에 알릴 수 있는 방법을 제공할 뿐만 아니라 뷰의 레이아웃을 다시 계산한 후 수행할 작업을 정의하기 위해 overriding을 제공합니다.

layoutSubviews()

  • 뷰와 뷰의 모든subview들을 repositioning, resizing을 처리하는 메서드
  • 현재 뷰와 모든하위뷰들의 location과 size를 제공합니다.
  • 모든 하위뷰들을 호출하기때문에 이 메서드는 무거운 작업입니다.
  • 뷰들의 frame을 recalculate할 때 시스템은 이 메서드를 호출하므로 프레임을 설정하고 위치지정 및 크기 조정을 지정하고 싶을 때 사용합니다.
  • view hierarchy(뷰의 계층구조)에서 layout refresh가 필요할 때 명시적으로 이메서드를 호출하면 안됩니다. 대신에 다른 메서드들을 사용합니다.
  • layoutSubviews가 완료되면 뷰를 소유한 뷰 컨트롤러에서 viewDidLayoutSubviews에 대한 호출이 발생합니다. 따라서 레이아웃이나 위치를 계산해서 정하는 경우 viewDidLoad, viewDidAppear에서가 아닌 viewDidLayoutSubviews에서 호출하는 것이 안정적입니다.

Automatic refresh triggers

개발자가 직접 작성하지 않아도 뷰의 레이아웃을 변경한 것을 자동으로 표시하는 여러 이벤트가 있습니다.

  • 뷰의 레이아웃 변경
    1. Resizing a view
    2. Adding a subview
    3. User scrolling a UIScrollView (layoutSubviews is called on the UIScrollView and its superview) layoutSubviews 는 UIScrollView 및 해당 Superview에서 호출됩니다
    4. User rotating their device (화면 회전)
    5. Updating a view’s constraints

이러한 목록들은 모두 뷰의 위치를 다시 계산한 후 자동으로 마지막에 layoutSubviews 호출로 가야할 것을 시스템에 전달합니다.

직접 layoutSubviews를 발생하기

setNeedsLayout()

  • 시스템에 뷰의레이아웃을 다시 계산할 필요가 있다고 전달합니다. 호출되는 즉시 실행되며 반환됩니다. 반환되기 전에 뷰를 실제로 업데이트하지않지만, 뷰가 다음 업데이트 주기에 뷰가 업데이트됩니다.
  • 반환되기전까지 간격이 있기 때문에 사용자에게 UI지연을 주의해야합니다.

layoutIfNeeded()

  • 뷰의 레이아웃업데이트가 필요한 경우 다음 updateCycle에 실행하기 위해 큐에 넣는 것 대신에 즉시 뷰의 레이아웃업데이트를 합니다.
  • 같은 runloop에서 이메서드를 두번 호출하면 두번째 메서드는 호출이 되지않습니다.
  • setNeedsLayout()와 가장 큰 차이점은 이 메서드가 반환되기전에 즉시 뷰업데이트가 발생하는 것이기 때문에 필요한 경우 비교해서 사용합니다. (이 메서드는 constraint를 변경하는 애니메이션을 할 때 유용합니다.)

Display

뷰의 display는 color,text,image,coreGraphics drawing(코어그래픽도면)을 포함하는 sizing(크기)와 positioning(위치)가 지정되지 않은 뷰 및 하위뷰들의 프로퍼티를 포함하고 있습니다.

draw(_:)

  • 뷰의 컨텐츠를 그릴 때 사용합니다. (하위뷰들에서는 호출되지 않습니다.)
  • 따라서 즉시 그리지 않을 경우가 아닌 다른 runloop에서는 호출하면 안됩니다.

setNeedsDisplay()

  • 뷰의 컨텐츠가 업데이트 되어야한다고는 하지만 실제로 그리기 전까지는 변경되지 않고 다음 updateCycle에서 변경됩니다.
  • 다음 updateCycle에서 뷰의 일부컨텐츠만 변경할 때 이 메서드를 호출합니다.

Constraints

오토레이아웃에서 뷰를 배치하고 다시그리는 단계

  1. constraints를 업데이트 (시스템은 뷰들의 constraints를 설정한후 계산합니다.)
  2. 레이아웃엔진이 뷰와 하위뷰들의 프레임을 계산합니다. 레이아웃 전달
  3. display는 뷰를 다시그릴 필요가 있을 때 다시 그리게됩니다.

updateConstraints()

  • 이 메서드를 사용하면 오토레이아웃을 사용한 뷰에서 dynamically(동적으로) constraints를 변경가능 합니다. (layoutSubviews()와 동작방식이 유사합니다.)
  • 변경될수 있는 constraints만 구현해야합니다. static(정적)인 constraints는 인터페이스빌더나, 뷰의 초기화 및 viewDidLoad()에서 구현해야합니다.

setNeedsUpdateConstraints()

  • 다음 updateCycle에 constraints를 업데이트할 경우 사용합니다.

updateConstraintsIfNeeded()

  • constraint update플래그를 확인한 후 runloop가 끝나기전에 즉시 updateConstraints()를 호출하여 constraints를 변경합니다.

invalidateIntrinsicContentSize()

  • 오토레이아웃에는 intrinsicContentSize프로퍼티가 있는데 다시 변경할 필요가 있을 때 플래그를 설정할 수 있습니다.

참고링크

profile
iOS 공부 중 🧑🏻‍💻

0개의 댓글