본문 바로가기

프로젝트/메모앱

025 ~ 027. Dark mode, iPad support and Mac catalyst (다크모드, 아이패드 지원 그리고 맥 카탈리스트)

Dark mode

좌측 하단의 Environment Overrides의 Appearance를 통해
시뮬레이터의 다크모드와 라이트모드를 전환할 수 있다.

사진에서와 같이 현재는 다크모드로 전환해도 인터페이스상의 큰 문제는 없다.
이는 앱을 제작 할 때 대부분 기본 컬러들을 사용했기 때문인데, 이 경우 darkmode에 자동으로 대응한다.
단, 셀에서 날짜를 표시하는 레이블들이 기본 색상이 아닌 Custom Color를 사용했는데,

기존에 설정했던 LightGray가 아닌 DarkGrey로 설정하는 경우 다크모드에서 시인성이 매우 안 좋은 것을 확인 할 수 있다.
이렇게 CutomColor를 사용 할 때는 다크모드에 자동으로 대응하지 못하기 때문에 두 가지의 경우를 모두 생각해 적용 할 필요가 있다.

물론, 위와 같은 문제를 해결 하는 방법이 있다.

다크모드를 지원하는 SystemColor 사용하기

iOS에서 제공하는 여러 컬러 옵션 중 'System', 'Secondary', 'Tertiary'로 시작하는 옵션은 다크모드에 자동 대응한다.
단, 모든 색상을구현해 둘 수 없기 때문에 선택의 폭이 좁다는 단점이 있다.

직접 Custom Color 생성하기

Asset에 'New Color Set'을 생성한다.

Color Set의 이름은 생성할 때 정하거나 좌측 상단의 이름을 더블클릭해 바꿀 수 있다.
두 개의 하얀 사각형을 Color Well 이라고 부르고, 좌측은 라이트모드, 우측은 다크모드에 표시할 색을 선택한다.

강의와는 조금 달랐는데,

컬러셋의 Appearances 부분이 기본으로 'Any, Dark'로 설정되어 있었다.
만약 두 개의 well이 보이지 않는다면 위와 같이 바꿔 줘야 할 필요가 있다.

이후 해당하는 ColorWell을 선택하고, Show Color Panel이나 기타 방법들로 원하는 색을 채워 넣는다.

이후 다시 Label의 Attribute Inspactor에서 추가 된 ColorSet을 찾아 적용한다.

이 부분에서도 강의와는 조금 다르게 진행 되었는데,
다크모드를 지원하는 컬러셋은 다크모드에서만 사용할 수 있다.
즉, 다크모드가 추가 된 iOS11 이후의 버전에서만 사용할 수 있어, 에러가 발생한다.

강의는 target OS가 iOS10 부터이고, 내 경우엔 target OS가 iOS11 부터로 해당 오류로 부터 자유롭다.
하지만 대응 방식을 알아 둬야 하기 때문에 강의와 같이 OS에 따른 예외처리를 진행한다.
이 때에는 코드에서 적용하고, 코드에서 분기할 수 있도록 구성한다.

//
//  MainListTableViewController.swift
//  test
//
//  Created by Martin.Q on 2021/07/21.
//

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
	let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell", for: indexPath)
	
	let data = DataManagement.shared.memoList[indexPath.row]
	cell.textLabel?.text = data.content
	cell.detailTextLabel?.text = reform.string(for: data.genDate)
	
	if #available(iOS 11, *) {
		cell.detailTextLabel?.textColor = UIColor(named: "dateTheme")
	} else {
    	cell.detailTextLabel?.textColor = UIColor.lightGray
	}

	return cell
}

#available을 사용하여 OS 버전에 따라 분기하도록 작성한다.
11 이상인 경우 색상을 새로 만든 컬러셋인 dateTheme으로 설정하고,
이하인 경우 기본으로 제공하는 lightGray를 정용하도록 한다.

해당 수정은 뷰어의 날짜 표시 label에도 동일하게 적용한다.

이렇게 storyboard에서 기본 값으로 돌려도 코드로 적용한 커스텀 컬러셋이 적용된 걸 확인 할 수 있다.

 

ipad support

공유기능

Xcode에서 작성한 앱들은 AutoLayout을 충실히 적용 했다면 기본적으로 Univeral App의 형태를 가진다.
Simulator를 iPad로 바꿔 실행해 보면

공간낭비가 심할 뿐, 대부분의 기능이 잘 작동 하지만 공유 기능은 제대로 작동하지 않는다.

iOS에서는 공유시트로 작동하던 UI가 아이패드에서는 PopOver로 대체되어 작동하는데,
이 UI는 View나 Button을 전달해 어디서 실행하는지를 지정해 줘야 한다.
공유시트에선 해당 없던 조건이지만, 팝오버에선 필수적인 조건이다.

//
//  ViewerViewController.swift
//  test
//
//  Created by Martin.Q on 2021/07/23.
//

@IBAction func shareMemo(_ sender: Any) {
	guard let memo = data?.content else {return}
	let temp = UIActivityViewController(activityItems: [memo], applicationActivities: nil)
	present(temp, animated: true, completion: nil)
	
	if let tempP = temp.popoverPresentationController {
		tempP.barButtonItem = sender
	}
}

해당 작업은 popoverPresentationController에 전달하는 것으로 해결된다.
단, 이 때 barButtonItem에 저장되는 데이터의 형식은 UIBarButtonItem이어야 하기 때문에
share 버튼의 sender의 자료형을 UIBarButtonItem으로 바꿔줘야 할 필요가 있다.

//
//  ViewerViewController.swift
//  test
//
//  Created by Martin.Q on 2021/07/23.
//

@IBAction func shareMemo(_ sender: UIBarButtonItem) {
	guard let memo = data?.content else {return}
	let temp = UIActivityViewController(activityItems: [memo], applicationActivities: nil)
	present(temp, animated: true, completion: nil)
	
	if let tempP = temp.popoverPresentationController {
		tempP.barButtonItem = sender
	}
}

따라서 코드를 위와 같이 한 번 더 수정한다.

이젠 공유기능이 아이패드에 한해 popover로 동작한다.

UI최적화

현재의 메모앱은 아이패드에서도 멀쩡히 동작하긴 하지만,
iOS에 비해 공간을 지나치게 낭비하는 느낌이 없지 않다.

리스트와 컨텐츠의 폰트 크기를 늘려 조금 더 보기 편하도록 만들어 본다.

storyboard에서 Font와 Color 앞에 '+' 버튼이 있는 것을 확인 할 수 있다.
해당 버튼이 있는 옵션은 작동하는 기기별로 옵션을 다르게 적용할 수 있도록 설정할 수 있다.

기기구별은 그리 세세하지 않다.
높이와 너비를 Compact와 Regular 두 가지로 구분해 CC, CR, RC, RR 총 네 가지로 구분한다.

이후 적용할 사이즈를 기입한다.
iOS에 해당하는 기본 사이즈가 아닌 아이패드에 해당하는 RR의 사이즈를 변경해야 한다.

또한 해당 작업은 List의 제목, 날짜 그리고 뷰어의 컨텐츠, 날짜 총 네가지에 대해 적용해야 할 필요가 있다.
(필요 없다면 필요한 부분에만 적용해도 무관하다.)

전과 후를 비교했을 때 컨텐츠의 폰트 크기가 커져 시인성이 늘어나고, 공간을 조금 더 효율적으로 사용하고 있다.

또한 아이폰에서는 이전과 동일한 사이즈로 컨텐츠들을 표시하고 있다.

 

Mac Catalyst

맥이 ARM 기반의 M1칩을 탑재하면서 iOS와 맥 앱 간의 전환을 전폭적으로 지원하고 있다.
Universal로 개발 된 앱을 쉽게 Mac에서도 구동할 수 있도록 기능을 제공하며, 이를 Mac Catalyst라고 부른다.

프로젝트 설정에서 Deployment Info > Target 에서 'Mac'을 선택하는 것으로 Mac Catalyst를 사용할 수 있다.

선택하면 활성화 여부를 묻는 알림이 등장하고, 동의하면 시뮬레이터에 사용중인 Mac이 추가된다.

해당 기능은 애플이 개발자들에게 편의를 제공해 주는 것이지, 완벽한 동작을 보장하지는 않는다.
따라서 네이티브가 아닌 Custom Control을 사용하거나, 3rd party framework를 사용하는 경우 생각보다 작업량이 많아질 수 있다.