Swift | 빠르게 빠르게 작성하고 기억하기
iOS 개발자로 성장하면서 빠르게 기록해야 하는 내용을 담아냅니다.
한결
UIKit - 쌓여있는 VC를 앱 사용성에 맞게 dismiss 시키고 특정 VC 보여주기
SceneDelegate의 scene 메서드 내부 구현처럼, 앱을 마치 처음 켠 것처럼 만들어버린다.
SceneDelegate에 정의한 window 객체를 불러와서, 새롭게 띄우려고 하는 VC를 갈아끼우는 느낌으로 코드가 동작한다.
viewDidLoad가 다시 돌기 때문에, 앱 전체의 테마를 바꾼다던지 로그인 여부 자체를 변경하는 것 등을 관리할 때 이전에 쌓은 페이지들을 다 dismiss 해주는게 좋을 수 있다.
Reaction
Comment
Share
한결
UIKit - CollectionView 가로 스크롤 UI
커머스 앱이나 배달 앱 등 비슷한 카테고리로 동일한 데이터를 좁은 View 안에서 보여주기 위해서 가로의 끝이 언제인지 알 수 없는 가로 스크롤 UI를 사용하곤 한다. iOS에서는 UICollectionView로 이런 가로 UI를 쉽게 생성할 수 있다.
컬랙션뷰를 구현하기 위해서는 delegate, datasource에 대한 위임, 커스텀 Item에 대한 등록 역시 필요하다. (이 부분은 테이블뷰 구현과 동일하다.)
Swift 자체에서 시스템 테이블로 제공하는 형식이 없다보니, 테이블뷰 구현과 다르게 컬랙션 아이템(테이블에서는 셀), 컬랙션 틀 자체에 대한 레이아웃을 랜더링 하기 전에 반드시 설정해줘야 한다.
*설정하지 않고 빌드해보면 아래와 같은 에러를 마주할 수 있다.
"UICollectionView must be initialized with a non-nil layout parameter"
UICollectionViewFlowLayout 클래스로 생성한 인스턴스에서 컬랙션 아이템, 틀에 대한 레이아웃을 지정할 수 있다. (내장 멤버 변수를 조정하여 설정 가능하다.)
itemSize - 말 그대로 각 아이템의 사이즈를 결정해준다.
scrollDirection - 당연히 스크롤 방향이다.
minimumLineSpacing - 컬랙션 뷰 내부에서 아이템들 간의 간격을 결정한다.
sectionInset - 컬랙션 뷰 내부의 아이템 그룹의 Edge에 대한 간격을 결정한다.
위와 같이 설정을 한다면, 아래 첨부된 영상처럼 가로 스크롤이 가능한 UI 구현이 가능하다.
00:07
Reaction
Comment
Share
한결
UIKit - Pagination (a.k.a. 무한 스크롤) - 계속 수정 예정
유저의 스크롤 시점에 따른 데이터 조회를 위해서 iOS에서는 페이지네이션을 기본으로 한다.
웹에서의 페이지네이션과는 그 방법 자체가 조금 다르다. 웹에서는 조회 가능한 데이터셋을 기준에 따라 정말 '페이지'로 구분해서 버튼 형식으로 구분했었던 것 같다. iOS에서의 페이지네이션은 웹에서 '무한 스크롤'이라고 부르는 형태를 페이지네이션이라고 지칭한다.
스크롤을 기반으로 데이터 조회 함수를 호출하는 시점을 조절하는 것이 핵심이다. iOS 화면이 스크롤 되어서 아래의 컨텐츠 뷰 영역이 뜨기 전에 미리 데이터를 fetching 하는 방식이 필요하다.
Off-Set 기반
주의사항: 데이터 fetching 중에, 데이터 전체 갯수에 변동이 (새로운 데이터가 fetching 중간에 갱신되는 경우) 있는 경우 원하는 결과가 되지 않을 수 있다.
Cursor 기반
스크롤 전, 후에 데이터가 어떻게 되는지의 차이를 이용하여 구현하게 된다.
특정 데이터 인스턴스에 Previous, Next의 키로 이전, 이후의 데이터셋을 미리 정해두고 데이터를 fetching 하는 방식이다.
채팅, SNS에서
Reaction
Comment
Share
한결
UIKit - 스토리보드 기반에서 코드 기반으로 시뮬레이터 작업 세팅하기
💡
스토리보드 + 코드 기반에서 코드 기반으로만 iOS 개발 작업을 할 수 있는 세팅 방법을 순서대로 기록합니다.
1. MainStoryboard 파일을 삭제한다.
사실 파일을 삭제할 필요까지는 없지만, 앞으로 사용할 일이 없기 때문에 굳이 남겨둘 이유도 없다.
2.
info.plist 파일에서 Storyboard Name 을 지워준다.
3.
프로젝트 설정 > Build Settings > Info.plist Values 항목에서 스토리보드 항목을 지워준다.
4.
SceneDelegate.swift 파일에서 scene 함수 내부에서 Window 객체에 엔트리로 연결하려고 하는 ViewController 인스턴스를 맵핑해준다.
Reaction
Comment
Share
한결
Swift - tableView.delegate = self 에서 프로토콜 타입을 할당해야 하는 자리에 self를 할당하는 이유는?
Swift 프로토콜에는 Protocol as Type, Delegation이라는 개념이 적용되기 때문이다.
Protocol as Type
Protocol's Delegation
클래스에 Protocol을 연결하여 위임자를 자기 자신의 인스턴스로 할당할 수 있다.
물론 동일 프로토콜을 적용한 다른 클래스의 인스턴스로 위임하는 것도 가능!
여기서는 tableView 라고 하는 프로퍼티의 일을 SomeView의 인스턴스가 직접 위임받아 처리할게! 라는 뜻으로 이해하면 된다.
Reaction
Comment
Share
한결
UIKit - View Class에 프로토콜로 클래스 이름이 할당된 타입 프로퍼티 지정하기
TableView에 커스텀셀을 등록하거나, 다른 Storyboard의 뷰를 연결하기 위해서 identifier 값을 지정하게 된다. 이럴경우 (나의 경우에는) 뷰 클래스 내부에 identifier라는 타입 프로퍼티를 지정해주는 편인데, 매번 클래스를 선언할 때마다 나의 타이핑 오류를 감안하기는 번거롭다. protocol, extension 을 이용하면, 프로젝트 단위로 이런 번거로움을 쉽게 해소할 수 있다.
1.
protocol은 특정 클래스나 구조체 등에 형태의 제약을 걸어주는 역할을 한다.
프로토콜을 적용하는 클래스가 반드시 identifier라는 타입 프로퍼티를 가지게 강제해본다.
2.
extension은 특정 클래스나 구조체 등의 기존 역할을 확장해주는 역할을 한다.
강제의 개념이라기 보다는
이런이런 역할도 할 수 있어! 로 기능을 확장하는 느낌이다.
extension에 미리 만들어둔 ViewClassIdentifier 프로토콜을 연결한다.
identifier라고 하는 타입 프로퍼티 작성을 강제했기 때문에 extension 선언 시에 반드시 작성해줘야 한다.
연산형 프로퍼티에 따로 getter, setter 를 부여하지 않으면 디폴트로 getter로 역할을 한다.
반환하는 부분에 describing: self 를 통해서 확장하는 View 클래스 자기 자신의 이름으로 값이 맵핑된다. (아주 나이스하다!)
3.
해당 extension이 적용된 View 객체들은 코드 생성시에 해당 프로퍼티를 초기화 하는 과정을 개발자가 직접 거치지 않아도 바로 타입 프로퍼티 형태로 접근이 가능하다.
Reaction
Comment
Share
한결
UIKit - 원하는 방향으로 layer.cornerRadius 부여하기
UIImageView, UIView 등등에 원하는 방향(좌상단, 우상단, 좌하단, 우하단)에만 radius 처리를 하는 방법은 간단하다. 전체에 cornerRadius 값을 주고, 부여하고자 하는 포인트를 masked하면 된다. 뭔가 피그마에서 이미지 틀을 만들고 그 안에 이미지를 마스킹 하는 것과 비슷하다.
아래에 깎으려고 하는 코너의 값 자체를 넣어뒀는데, 사실 외울 필요가 전혀 없다.
생각해보면, 뷰에서 좌측은 X좌표가 뷰의 가장 minimum한 값이고 뷰의 하단은 Y좌표가 뷰의 가장 maximum한 값이기 때문이다. 그래서 머리속으로 깎으려고 하는 코너의 위치가 어떻게 되는지 생각만 하면 된다.
좌상단: .layerMinXMinYCorner
우상단: .layerMaxXMinYCorner
좌하단: .layerMinXMaxYCorner
우하단: .layerMaxXMaxYCorner
Reaction
Comment
Share
한결
XCode StoryBoad 상 세그웨이를 이용한 화면전환이 아닌 코드로 화면 전환하기
왜 코드로?
스토리보드에서 세그웨이를 연결해서 하면 화면간 연결이 편하지 않을까?
⇒ 세그웨이를 끌어다가 연결하는건 편하지만, 연결을 위한 버튼이나 테이블 뷰의 셀 등을 직접 만들어서 화면으로 하나하나 연결해줘야 하는 불편함이 생긴다. 물론 연결되는 화면을 일일이 그려야 한다는 번거로움도 커진다.
화면 전환?
전환되는 방식을 먼저 고려하자 (정답은 없다.)
특정 콘텐츠(메뉴)의 상세 정보 ⇒ 보통 우측에서 Show 방식으로
특정 콘텐츠(메뉴)의 기존과 다른 정보 ⇒ 보통 아래에서 위로 Modal 방식으로
그러면 어떻게?
1.
스토리보드 가져오기
2.
스토리보드 내 전환하려는 화면 가져오기
3.
화면 띄우기
See more...
Reaction
Comment
Share
한결
[Swift - 문법]
구조체의 연산 프로퍼티
다른 (저장형) 인스턴스 프로퍼티를 이용해서 말 그대로 '연산'을 담당하는 구조체의 속성.
초기화를 하지 않고, 구조체 자체에서 연산을 하기 때문에 메모리의 힙/스택 영역을 차지하지 않음.
함수(메서드)는 아닌데 마치 함수처럼 작성함.
생성한 인스턴스에서 멤버 프로퍼티를 조회하는 것처럼 사용하면 됨.
let 키워드로 선언은 안되고 무조건 var 키워드로 선언해야 함.
Reaction
Comment
Share
한결
Swift Extension으로 반복적인 코드 관리하기
Extension은 기존에 존재하는 타입을 확장하여 기능성을 높여준다. (Add functionality to an existing type.)
Class, Struct는 물론이고 Protocol, View에 대한 인스턴스 메서드나 계산이 들어간 인스턴스 프로터피도 새롭게 추가할 수 있다.
Reaction
Comment
Share
한결
ATS Policy
HTTP와 HTTPS와 같은 Apple(App) Transport Security 정책을 말한다.
iOS 10+ 에서 적용된 보안 정책으로, 쉽게 생각하면 데이터를 받아오는 URL 구조에서 보안정책을 무시한 내용이 담겨있으면 (ex. http로 통신하는 URL) 앱에서 로드를 거부한다.
물론 프로젝트 plist에서 ATS > Allow Arbitrary Loads 설정을 YES로 강제하면 HTTP 프로토콜 내에서도 통신이 가능하게 허용할 수는 있다.
Reaction
Comment
Share
한결
XIB과 NIB 파일
XIB: XML Interface Builder
XML은 내가, 그리고 모두가 알고 있는 것과 동일하게 그 마크업 언어가 맞다.
XML로 되어 있는 인터페이스를 만드는 도구를 XIB라고 이해하면 쉽겠다.
스토리보드 형태로 되어 있어서 쉽게 인터페이스를 디자인하고 개발할 수 있다. 물론 코드 파일과 연결시켜서 코드베이스로도 통제할 수 있다.
NIB
XIB에서 정의된 인터페이스의 뷰나 액션이 정의된 XML 기반의 컴파일된 파일이다.
쉽게 생각해서 XIB가 컴파일된 파일이라고 보면 된다.
요 아티클에서 알아본 파일 관리 시스템에서 앱 번들 디렉토리에 저장되어, 런타임이 실행되는 시점에 불러와져서 화면을 그린다. 그 화면이 켜질때 불러와진다.
앱 개발에 사용하는 방식은 학습 내용 정리 블로그에 아티클로 정리할 예정이다.
Reaction
Comment
Share
한결
UIViewController + UITableView vs. TableViewController
TableViewController에서 테이블 형태의 뷰를 만들어가면,
이후 앱 디자인이 변경될 경우 더 많은 작업을 해야 할 수 있겠다. 혹은 ViewController자체를 바꿔야 할 수도 있을 것 같다.
또한, 자유롭게 UI 요소를 컨트롤하기 어렵다는 한계를 마주해야 한다.
그래서 보통,
UIViewController 위에다가 UITableView 요소를 올리는 방식으로 개발 작업의 자유도를 높인다.
물론, 이렇게 작업할 경우 상속 관계의 차이가 있어서 테이블 작업을 할 때의 방식이 차이가 날 수 있다. (그냥 난다라고 보면 된다.)
그러면, UIViewController + UITableView 조합으로 코드는 어떻게 작성할까?
1.
UIViewController의 특정 위치에 UITableView를 얹는다. 필요에 따라서 TableView 객체를 Outlet 속성으로 잡는다.
2.
UIViewController 클래스를 상속받은 클래스에 TableView를 다루기 위한 두 개의 프로토콜을 연결한다.
UITableViewDelegate
UITableViewDataSource
3.
viewDidLoad 메서드에서 TableView의 두 프로토콜을 클래스 인스턴스 자체로 설정해준다.
See more...
Reaction
Comment
Share
Share
한결
ATS Policy
HTTP와 HTTPS와 같은 Apple(App) Transport Security 정책을 말한다.
iOS 10+ 에서 적용된 보안 정책으로, 쉽게 생각하면 데이터를 받아오는 URL 구조에서 보안정책을 무시한 내용이 담겨있으면 (ex. http로 통신하는 URL) 앱에서 로드를 거부한다.
물론 프로젝트 plist에서 ATS > Allow Arbitrary Loads 설정을 YES로 강제하면 HTTP 프로토콜 내에서도 통신이 가능하게 허용할 수는 있다.
👍