하나의 제품을 지원하는 설계 시스템을 구축하는 것은 쉬운 일이 아닙니다. 확장성을 위해 동시에 견고하고 유연해야 합니다. 도전적이긴 하지만 많은 훌륭한 리소스가 팀이 시각적으로나 프로그래밍 방식으로 좋은 시스템을 구축하는 데 도움이 되는 유용한 원칙과 접근 방식을 공유하고 있습니다. 어깨를 나란히 하고 이 기사는 SwiftUI
에서 좋은 시스템을 구축하는 데 집중하여 사람의 손길이 닿지 않은 땅에 기여하려고 합니다. .
이 기사를 작성하는 이유
뉴욕 ITP에서의 첫 여름 동안 저는 Line Break Studio에서 iOS 개발자 인턴으로 일할 수 있는 기회를 갖게 되어 운이 좋았습니다. 나에게 할당된 한 가지 작업은 두 단계로 디자인 시스템을 구축하는 것입니다. 첫 번째는 Sketch에서 시각적으로, 그 다음에는 SwiftUI
에서 프로그래밍 방식으로 . 새로운 프레임워크를 실험하고 이를 사용하여 디자인 시스템을 구축하는 경험은 훌륭했지만 그 과정에서 버그가 있었습니다. 그렇기 때문에 커뮤니티와 경험을 공유하고 개발 프로세스를 더 쉽게 만들 수 있기를 바랍니다.
SwiftUI란 무엇입니까
Apple은 WWDC 2019에서 이 획기적인 새 프레임워크를 출시했는데, 이는 수년 중 최고 중 하나입니다. 웹 개발자의 관점에서 SwiftUI
의 프로젝트 개발 경험 기존의 프론트엔드 스택과 프레임워크에서 어느 쪽과 더 가깝습니다.
프로그래밍 인터페이스와 상태 관리가 이전보다 훨씬 쉬워졌기 때문에 이것은 확실히 멋진 움직임입니다. 그리고 이 개선 사항의 가장 좋은 점은 UIKit과 SwiftUI를 원활하게 통합할 수 있다는 것입니다. SwiftUI의 기본을 배우려면 Apple에서 제공하는 공식 튜토리얼이 매우 유용합니다.
데모 프로젝트
데모 목적으로 Line Break Studio에서 구축한 디자인 시스템의 단순화된 버전을 올렸습니다. 버튼 세트입니다. 타이포그래피의 두 가지 하위 수준 부분 위에 구축된 다양한 형식의 구성요소 및 colorPalette .
프로젝트는 GitHub에 공개되어 있으며 Xcode 11 Beta 5
를 사용하고 있습니다. 개발을 위해. 디자인 시스템 관리 허브로서의 Airtable 기반(워크플로 관리에 대해 자세히 알아보기)도 참조용으로 공개됩니다.
건축 설계 시스템의 원칙
코드의 디자인 시스템은 디자이너와 개발자 사이의 미들웨어입니다. 시스템 개발자는 디자인 시스템에서 시각적 형태의 입력을 받아 향후 개발을 위해 동일한 API를 생성합니다. 코드로 이 시스템을 완성하려면 다음 두 가지 원칙을 인식해야 합니다.
1. 토큰으로 통신
기본적으로 프로그램에 디자인 시스템을 포함하는 목적은 더 나은 코드 관리나 개발 효율성이 아니라 보기 디자인 파일과 일치합니다. 이러한 목표를 달성하려면 특정 색상, 글꼴, 크기 또는 시각적 요소를 나타내는 토큰을 사용하는 것이 팀의 개발자, 디자이너 및 관리자 간의 커뮤니케이션 품질을 유지하는 데 중요합니다.
2. 계층 구조 수준
EightShapes의 기사에서 "옵션 없이는 결정을 내릴 수 없기 때문에 먼저 옵션을 표시하고 다음에 결정을 내려야 합니다"라고 지적합니다.
이러한 종류의 주문 아키텍처는 서로 다른 수준 간의 결합 정도를 느슨하게 하여 가능한 수정에 대해 더 많은 유연성과 동적을 제공합니다. 내가 레벨을 구성하는 방법은 아래에서 위로 재료 → 기본 → 토큰의 순서입니다. 하지만 어쨌든 팀이 편안하게 사용할 수 있습니다.
코드 자세히 알아보기
다음 섹션은 우리의 경험을 바탕으로 지적하고 싶은 하이라이트 목록입니다. 전체 코드를 보려면 GitHub 리포지토리를 방문하세요. 개선 사항에 대한 피드백이나 비판을 환영합니다.
1. 계층 구조 수준
가장 높은 수준에서 토큰을 구성하기 위해 낮은 수준에서 재료를 쌓는 두 가지 방법이 있습니다.
enum
사용 유형 안전 및 코드 리터러시
코드에서 enum을 그룹화 래퍼 또는 함수의 매개변수로 사용하는 이점은 이미 잘 알려져 있습니다. 여기서 언급할 가치가 있는 한 가지 사항은 계층 구조 수준의 구현입니다.
글꼴 크기(CGFloat
) 및 글꼴 이름(String
), 가장 낮은 수준에서, 우리는 그것을 엉망으로 만들고 싶지 않기 때문입니다. 그러나 원시 값은 열거형에서 리터럴이어야 하므로 case
을 할당할 수 없습니다. 다른 열거형의 값입니다.
이 문제를 해결하기 위해 getValue
함수를 구현합니다. , switch
의 원시 값을 반환합니다. 필요한 경우.
struct
사용 더 쉬운 구조
enum은 훌륭하지만 경우에 따라 고유한 기능이 필요하지 않습니다. 예를 들어 Xcode
이기 때문에 동적 색상 처리의 무거운 작업을 처리하고 API 끝점에서 매개변수 옵션이 필요하지 않습니다. 우리는 단순한 두 수준의 구조로 색상 팔레트를 설정할 수 있습니다.
2. API
의 명확하고 직관적인 이름 지정 끝점
명명 규칙은 토론과 토론을 위한 또 다른 광범위한 주제입니다. 기본적인 Swift 규칙 외에도 우리가 준수하는 유일한 두 가지 규칙은 1) 두문자어를 사용하지 않는 것과 2) 간단하게 만드는 것입니다. 예를 들어, 타이포그래피와 색상 시스템을 사용하기 위해 새로운 끝점을 만드는 대신 Font 및 Color 구조체에서 확장을 만듭니다. 이 접근 방식은 개발자가 익숙하지 않은 API 이름을 외우려는 노력을 줄여줍니다.
3. 두 가지 모드에서 동적으로 색상 세트 관리
그래서 다크 모드는 업계의 표준이 되었고 iOS와 Android 팀 모두 이 기능을 구현했습니다. 이는 사용자에게 좋은 추세이지만 색상 세트, 특히 회색조 세트를 관리하고 이름을 지정하는 것을 포함하여 디자이너와 개발자에게 몇 가지 문제를 야기할 수 있습니다.
흰색과 같은 용어를 사용하여 회색조 색상에 대해 동적으로 생각하고 의사소통하기 , 빛 , 검은색 또는 어두운 작동하지 않습니다. 동적 색상 #000000
(HEX의 검은색) 검은색 또는어두운 light color scheme
, #FFFFFF
로 바뀌어야 하는 이 특정 색상에 대해 어떻게 이야기합니까? (HEX의 흰색), dark color scheme
? 기본어두움 또는 lightDark ?
기존 접근 방식에서 그레이 스케일 동적 색상 세트의 이름을 지정하는 것은 매우 혼란스럽습니다. 이러한 혼동을 피하기 위해 theme
를 사용합니다. 및 contrast
light
에서 한 세트의 색상을 관리하기 위해 및 dark
대신 계획.
그레이 스케일 색상은 반대 색상 모드에서 항상 반전될 필요는 없습니다. 밝은 색상은 밝은 상태로 유지되고 어두운 색상은 어두운 상태로 유지되는 이러한 상황에서 간단히 이름을 밝음 또는 어둡게 지정합니다.
이 이름 지정 방법에 대해 머리를 숙이면 Xcode
에서 이 색상 팔레트 아키텍처를 쉽게 관리할 수 있습니다. . 색상 세트를 만들려면 새 Asset Catalog
를 만드세요. 파일 → 새 Color Set
추가 → Appearances
변경 Any, Light, Dark
로 할 것입니다.
4. environment
설정
SwiftUI 프레임워크의 한 가지 멋진 기능은 대상 보기에서 환경 값을 제어하는 기능을 제공하는 환경 수정자입니다. 건물 디자인 시스템 측면에서 이 기능은 루트 수준에서 앱의 글꼴을 변경하는 편리한 접근 방식을 제공합니다. environmentValue
사용의 또 다른 장점 개발 중인 밝고 어두운 색 구성표를 변경하고 테스트하는 것입니다.
5. buttonStyle
및 버튼 레이블
UIKit의 예전에 비해 SwiftUI에서 재사용 가능한 버튼을 구성하는 것이 훨씬 쉽습니다. 버튼 보기는 action
의 두 부분으로 구성됩니다. 클로저(버튼을 누를 때 발생하는 이벤트) 및 label
(버튼의 몸체). 그런 다음 뷰를 수정자 buttonStyle
로 연결할 수 있습니다. . 재사용 가능한 버튼을 만드는 방법에 대한 자세한 내용을 보려면 포괄적이고 유용한 Alejandro의 자습서를 읽는 것이 좋습니다.
맞춤형 버튼 구성 요소에서 첫 번째 단계는 TokenButtonLabel
을 포함한 두 개의 구조체를 만드는 것입니다. 및 TokenButtonStyle
. 이 두 구조체는 디자인 파일에 있는 버튼 유형에 따라 프로그래밍됩니다. 예를 들어 레이블에는 아이콘과 텍스트의 두 가지 유형만 있습니다. 각 유형에는 init
가 있습니다. 새 인스턴스에 대해 다른 매개변수로 설계된 함수입니다.
반면에 버튼 스타일에는 원 아이콘, 아이콘, 캡슐 및 텍스트의 네 가지 주요 유형이 있습니다. ButtonStyle
를 팔로우하려면 프로토콜, makeBody
func를 구현해야 합니다. 이 함수는 configuration
를 가져옵니다. 속성, 기본 isPressed
제공 버튼이 눌렸는지 여부를 모니터링할 값입니다.
마지막으로 TokenButtonLabel
위에 스태킹 및 TokenButtonStyle
, 버튼 구성 요소 API의 끝점은 TokenButton
입니다. - 시각 디자인 시스템의 버튼 유형에 따라 버튼의 콘텐츠와 스타일을 함께 묶는 그룹화.
6. AnyView
래퍼로
makeBody
을 다룰 때 ButtonStyle
에서 가져온 함수 프로토콜에서 View
작업에 유용한 팁을 찾았습니다. . 보기를 변수에 저장하려면 유형 주석을 AnyView
로 표시할 수 있습니다. , SwiftUI에서 보기의 일반 컨테이너로 작동합니다.
우리의 경우 configuration.label
에 opacity modifier를 추가하기를 원하기 때문에 각 switch
에서 반복적으로 수행하는 대신 모든 유형의 버튼에 이 경우 수정자를 끝에 모두 연결하는 것이 더 합리적입니다. AnyView
의 이점을 사용하여 이 패턴을 달성할 수 있습니다. 이런 식으로:
7. mutating
으로 뷰 수정자 빌드 기능
버튼의 스타일을 동적으로 업데이트하기 위해 자체 수정자를 만들 수 있습니다. 먼저 보기에서 사용자 정의된 변경 가능한 상태 속성을 인스턴스화한 다음 mutating
을 만듭니다. Self
를 반환하는 함수 대상 상태 속성을 업데이트한 후 입력합니다.
8. 까다로운 테두리 스타일
SwiftUI의 한 가지 단점은 원형 테두리가 있는 원 모양을 스타일링하는 것이 전혀 간단하지 않다는 것입니다. 나는 잠시 동안 고심하다가 마침내 여기 StackOverflow에서 해결책을 찾았습니다. clipShape
및 overlay
작동하려면 수정자가 필요합니다.
결론
SwiftUI는 Apple이 만든 놀라운 개선 사항입니다. 결함이 여전히 존재하지만 이를 통해 강력하고 유연한 디자인 시스템을 구축하고 iOS에서 더 나아가 복잡한 UI를 구축하는 것이 그 어느 때보다 효율적입니다. 이 기사가 UI를 구축하려는 모든 iOS 팀에 도움이 되길 바라며 피드백은 언제나 환영합니다!
? vinceshao.com에서 내 작업에 대해 더 읽어보기 / Twitter 또는 LinkedIn에서 나를 팔로우하세요.