[Swift] View Controller Programming

simoniful·2021년 10월 15일
0

Swift

목록 보기
4/9
post-thumbnail

Function

어떤 컴퓨터 언어에서던지 로직(기능)을 실행하기 위한 조각으로서 함수 선언과 사용은 일반적입니다. swift에서도 함수는 1급 객체로 활용됩니다.

  1. 변수나 상수에 저장 및 할당 할 수 있어야 한다.
  2. 파라미터로 전달 할 수 있어야 한다.
  3. 함수(객체)에서 return 할 수 있어야 한다.
  4. 비교 연산(==, equal)을 적용할 수 있다. 다만 이를 swift는 권장하지 않습니다

🔗 1급 객체(first-class object)란?

Function / Method

객체로 부터 독립적 / 종속적 차이
함수가 객체의 프로퍼티로 저장된다면 이것은 메소드이다.

  • 함수가 메소드를 아우르는 포괄적인 용어입니다.
  • 함수는 객체로부터 독립적이며, 메소드는 객체에 종속적입니다.
  • 메소드는 거의 모든 면에서 함수와 동일하지만, 2가지 다른 점이 있습니다.
    • 메소드는 호출된 객체에 암시적으로 전달된다.
    • 메소드는 클래스 안에 있는 data를 조작할 수 있다.

Parameter vs Argument

Parameter는 매개변수 즉 함수의 선언 속에서 나열되는 변수입니다.
Argument는 인자, 함수의 호출 속에서 전달 혹은 입력되는 입니다.

func foo(p1: Int, p2: Int) {} 
foo(1, 2)

Parameter Name vs Argument Lable

Parameter Name은 함수 내부에서 활용하는 매개변수의 이름으로 함수 내부에서는 그 매개변수를 해당 이름으로 호출하여 사용합니다.

func foo(p1: Int, p2: Int) {
  print(p1 + p2)
}
// p1과 p2가 각각 Parameter Name이 된다.

Argument Label는 외부에서 함수를 호출할때 인자를 전달하기 위한 이름으로, 함수 외부에서는 해당 Argument Label로 개체를 명명합니다.

func foo(num1 p1: Int, num2 p2: Int) {
  print(p1 + p2)
}
let argu1 = 1
let argu2 = 2

foo(num1: argu1, num2: argu2)
// num1과 num2가 각각 Argument Label이 된다.

함수를 호출하면서 num1, num2라는 Argument Label에 자리에 argu1, argu2 라는 인자를 전달합니다. 이 후 p1과 p2라는 Parameter Name을 가진 매개변수에 할당되어 함수블럭 내부 로직을 거치게 됩니다.


Wildcard Pattern

Wildcard Pattern은 사용하지 않는 값에 대해서 사용할 수 있는 패턴입니다. 해당 변수 / 상수를 어디에서도 사용하지 않는다면 호출될 필요가 없으므로 이름을 별도로 작성할 필요가 없습니다.

let a = "Hello Swift"
let _ = "Hello Swift"

다양한 상황에서 사용되는데 Argument Label을 생략하고 싶은 경우, 스위치 문에서 튜플 중 하나만 값을 체크하고 싶은 경우 등에서 쓸 수 있습니다.


Overload / Override

Overload

전산학에서 오버로드(overload)는 객체 지향에서 하나의 함수 또는 연산자가 입력에 따라 여러 가지 동작을 하도록 하는 것을 말합니다.
같은 함수의 이름을 가지고 있지만 매개변수, 리턴타입 등을 다르게 하여 다양한 유형의 호출에 응답이 가능하게 구성할 수 있습니다.
swift는 해당 오버로드 기능을 허용하며, 함수 / 서브스크립트 / 생성자에서 사용할 수 있습니다.

func sum(_ a: Int, _ b: Int) -> Int {
    return a + b
}
 
func sum(_ a: Double, _ b: Double) -> Double {
    return a + b
}
 
func sum(_ a: String, _ b: String) -> String {
    return a + b
}

sum(1, 2) // 3
sum(1.0, 2.0) // 3.0
sum("a", "b") // "ab"

다만 함수 오버로딩에서 규칙이 있는데 명확하게 구분이 되지 않는 경우는 에러가 발생하게 됩니다.

func sum(lhs: Int, rhs: Int) -> Int {}
func sum(lhs: Int, rhs: Int) -> Double {}

Override

서브 클래스는 슈퍼 클래스에서 상속할 메서드, 프로퍼티, 서브스크립트를 서브 클래스에서 원하는대로 구현(재정의) 할 수 있는데, 이 것을 "오버라이딩(overriding)"이라 라고 합니다

물론 무조건적인 오버라이딩이 가능한 것은 아니고 상속에 대한 개념에 대하여 알아야하며 편의에 따른 조건이 존재한다. 프로퍼티의 경우 저장 속성만 추가할 수 있고, 이름과 타입을 반드시 명시해야하고, final을 붙이면 더 이상 상속이 불가능하거나 오버라이딩이 불가능 등

🔗 상속(Inheritance) 정복하기 1
🔗 상속(Inheritance) 정복하기 2

윗 부분을 이해하려면 프로퍼티 개념에 대해서 이해가 필요하기 때문에 클래스 및 구조체 영역에서 다시 한 번 다뤄볼 예정입니다. 우선 기본적인 개념에 대한 코드를 살펴봅시다.

class Person {
  let firstName: String
  let lastName: String
  init(firstName: String, lastName: String) {
    self.firstName = firstName
    self.lastName = lastName
  }

  func fullName() -> String {
    print("\(firstName) \(lastName)")
  }
}

class Korean: Person {
  override func fullName() -> String {
    print("\(lastName firstName)")
  }
}

영어권에서는 이름을 firstName, 성을 lastName으로 이름, 성 순으로 부르지만 한국인은 성, 이름 순으로 이름을 부릅니다. 자식 클래스 Korean에서는 fullName을 호출하는 동작을 바꾸고 싶기때문에 부모 클래스 Person에서 받아온 메서드를 재정의 했습니다.


AutoLayout

기존의 Frame-Based Layout과 다른 View 객체들 간의 관계를 이용하여 View 객체의 위치와 크기를 자동으로 결정하는 Layout System입니다. 이 때 관계 설정을 위해서 Constraint을 사용합니다.

따라서 Swift에서는 UI를 구성할 때 디바이스 별 다른 크기와 비율, 가로모드를 모두 동일하게 적용시키기 위해서 해당 개념을 활용하여 화면을 구상하며, 한 번의 작업으로 여러 구성에 대응가능하도록 지원하고 있습니다.

뷰의 위치 관점

    1. 상대 뷰와 비교했을 때 기준 뷰의 위치
    1. 부모 뷰와 비교했을 때 커지거나 줄어들면 뷰의 위치가 변경 되는지? 그리고 그 위치가 변경되는 규칙이 존재하는지?
    1. 기준 뷰의 콘텐츠가 정적인지 동적인지, 동적일 경우 어떻게 뷰의 위치를 지정할 것인지?
    1. 기준 뷰가 상대 뷰에 대한 가까이 또는 멀리 있는지, 그리고 최소 거리는 얼만지?

뷰의 크기 관점

    1. 상대 뷰와 비교했을 때 기준 뷰의 크기
    1. 부모 뷰와 비교했을 때 커지거나 줄어들면 뷰의 크기가 변경 되는지? 그리고 그 크기가 변경되는 규칙이 존재하는지?
    1. 기준 뷰의 콘텐츠가 정적인지 동적인지, 동적일 경우 콘텐츠의 크기에 따라 뷰의 크기도 변경 되는지?
    1. 뷰를 늘리거나 줄일 수 있는 범위에 제한이 있는지?

예시

A뷰의 오토레이아웃

  1. A뷰의 위치는 부모 뷰의 윗변으로 부터 20, 왼쪽변으로 부터 20 떨어져있다.
  2. A뷰의 크기는 부모 뷰에 대해서 상대적이지 않다.
  3. 부모 뷰의 크기 변화에 대하여 A뷰 크기는 상대적인 변경이 없다.
  4. A뷰는 정적인 크기를 가지며 width: 200, height: 100이다.

B뷰의 오토레이아웃

  1. B뷰는 다른 뷰와 어떤 관계에 있는지?
    B뷰의 왼쪽변은 A뷰의 오른쪽변에 25 떨어져있고,
    B뷰의 윗변은 A뷰의 윗변과 동일하게 정렬된다.
    B뷰의 높이는 A뷰 높이의 1.5 배이다.
  2. B뷰의 크기가 다른 뷰의 대해 상대적인지? 조건은 무엇인지?
    너비와 높이가 상대적이다.
    너비의 경우 A뷰의 오른쪽변과 부모 뷰의 오른쪽변에서 일정 거리 떨어져 있고
    높이는 A뷰에 대해서 1.5배의 높이이다.

Constraint

설정한 두 View 객체(FirstItem, SecondItem)의 상대성을 기준

  • Attribute: Top, Bottom, Leading, Trailing(상하좌우 위치) Width, Height(크기)
  • Multiplier: Relative ratio - 상대적 비율
  • Constant: Absolute distance - 절대적 거리
  • Relationship: equal, greater than or equal, less than or equal - 최대 / 최소 / 항등 설정

레이아웃에서 View 객체 간의 관계 설정은 위의 4가지 항목에 대한 코드로 작성된 선형 방정식을 통하여 설정되게 됩니다.


Priorty

여러 constraint에 대한 우선 순위를 선정하여 적용을 조정, 충돌 해결 가능

Constraint priority(제약 조건 우선 순위)

  • 제약 조건 우선 순위는 오토 레이아웃이 충족하기 위해 어떤 제약이 더 중요한지 결정하는 것
  • 우선순위는 1에서 1000사이의 값을 사용하여 정의할 수 있습니다.
  • 우선순위 1~999는 선택 사항이며 우선순위 1000은 필수사항입니다.
  • 새로운 제약을 추가할 때 기본 제약 우선순위는 1000으로 정의됩니다.

Content Hugging Priorites(콘텐츠 허깅 우선 순위)

  • 콘텐츠 허깅 우선 순위는 오토 레이아웃이 고유 콘텐츠 크기보다 더 크게 늘어나는 뷰를 결정하는데 도움이 됩니다.
  • 각 뷰에는 가로, 세로 콘텐츠 허깅 우선순위가 있습니다.
  • 콘텐츠 허깅 우선 순위가 높은 뷰는 늘어나는 것에 대한 높은 저항력을 나타냅니다.
  • 허깅 우선순위가 높으면 늘어나기 힘들고, 낮을 수록 잘 늘어납니다.

Compression resistance priorities(압축 저항 우선 순위)

  • 압축 저항 우선 순위는 오토 레이아웃이 고유 콘텐츠 크기보다 작게 축소되는 뷰를 결정하는데 도움이 됩니다.
  • 각 뷰에는 수평, 수직 압축 저항 우선 순위가 있습니다.
  • 우선순위가 높을 수록 줄어 드는것에 대한 높은 저향력을 나타냅니다.
  • 압축 저항 우선 순위가 높으면 줄어들기 힘들고 낮을 수록 잘 줄어듭니다.
  • 각 뷰에는 기본 750의 수평, 수직 압축 저항 우선 순위가 있습니다.
  • 콘텐츠 허깅 우선 순위와는 달리 모든 뷰 객체는 뷰 타입이나 인스터스화 방법에 관계없이 동일한 기본 압축 저항 우선순위를 갖습니다.

Intrinsic content size

뷰가 콘텐츠를 기반으로 차지하는 크기. 고유 콘텐츠 크기를 통하여 뷰의 크기를 조정가능

아크릴 상자(뷰)안에 풍선(콘텐츠)에 바람을 많이 넣은 상태, 바람을 빼는 상태를 생각하면 고유 콘텐츠 크기가 이해가 할 수 있습니다. 아크릴 상자 안에서만 풍선의 크기는 결정되며 다른 아크릴 상자와는 전혀 관계가 없습니다.

🔗 Auto Layout

profile
소신있게 정진합니다.

0개의 댓글