스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
멋진 Swift Playgrounds용 콘텐츠 만들기
Swift Playgrounds를 위해 디자인된 안내식 교육 콘텐츠를 빌드하는 방법을 알아보세요. 완료된 샘플 코드 프로젝트에 가이드를 추가하는 방법을 함께 알아보시기 바랍니다. 학습자가 자신만의 코드로 프로젝트를 확장하도록 장려하는 관련 코드와 선택 사항인 실험 과제를 보여주기 위해 러닝 센터에 과제를 추가하는 방법을 시연합니다.
리소스
관련 비디오
WWDC22
-
다운로드
♪ ♪
안녕하세요 Stephanie Angulo입니다 Marcus Jackson입니다 저희는 Swift Playgrounds Content 팀의 소프트웨어 엔지니어입니다 오늘 여러분들께 Swift Playgrounds를 위한 매력적인 컨텐츠를 만들 도구를 소개해 드리겠습니다 Swift Playgrounds 4에서는 iPad와 Mac에서의 앱 개발이 도입됐습니다 이는 App Store를 위한 앱을 만들 방법을 배우기에 최적의 방법이죠 우리 팀은 여러분들이 앱 개발의 기본에 대해 배우는 데 도움이 될 수많은 튜토리얼과 샘플 코드 제품들을 배포했습니다 우리가 다루는 주제는 관찰 가능한 데이터 모델을 사용한 동적 SwiftUI 앱 만들기 SwiftUI 애니메이션과 도형으로 보기 사용자화하기를 포함해 더 어려운 비동기 데이터 가져오기 같은 주제까지 다룹니다 오늘 세션에서는 우리의 새로운 교육 체계에 대한 개요를 제공하고 프로젝트 가이드 모듈로 컨텐츠를 작성하고 워크스루와 실험을 통해 몰입형 교육 경험을 구축할 것입니다 시작해보죠 학습자가 '앱으로 계속하기' 튜토리얼을 완료하면 최종적으로 'Emoji App'을 만들게 됩니다 이 앱에서는 학습자가 가장 좋아하는 동물 목록을 들여다보고 그 동물들의 크기와 색상을 바꿀 수 있으며 동물을 탭해서 'Creature Dance' 보기에서 동물들이 춤 추는 것을 볼 수 있습니다
이 춤은 재밌지만 저는 조금 더 실제 댄스 파티의 분위기로 만들고 싶습니다 그러니 학습자들에게 보여줄 추가적인 기능을 더해보겠습니다
여기 제가 'Creature Dance' 보기에 코드를 조금 더했습니다 모든 파티에는 댄스 플로어가 필요합니다 그래서 10x10 격자를 만들어 보기의 배경으로 설정했습니다
각 격자의 타일은 사용자 정의 보기 변경자를 이용해 무작위로 색이 업데이트됩니다 그루브가 느껴지죠?
그리고 가장 좋아하는 동물이 도움 없이 확실히 춤을 추도록 몇 가지 사용자 정의 변경자를 만들어 동물들이 움직이는 규모나 위치 회전을 설정했습니다
모든 사용자 정의 변경자의 애니메이션은 repeatForever로 설정돼서 동물들이 새로운 댄스 플로어에서 밤새 춤 출 수 있습니다
마지막으로, 댄스 플로어를 진짜로 불태우기 위해 보기의 위쪽에 디스코볼 애니메이션을 추가했습니다
이 마지막 손길로 모든 것이 합쳐져 궁극의 댄스 파티가 됩니다 이 프로젝트를 꽤 많이 변경했는데요 사용자 정의 보기 변경자의 세부 사항은 건드리지도 않았어요 이를 학습자에게 어떻게 설명할까요? 학습자를 Apple의 문서로 안내해도 되지만 여러분의 Swift Playgrounds 프로젝트 코드로 이런 개념을 가르쳐주는 방법도 있습니다 우리 팀은 여러분과 같은 작성자가 학습자를 위한 매력적인 인앱 경험을 만들 수 있도록 이 새로운 교육 체계를 만들었습니다 오늘은 Swift Playgrounds 4에서 이 앱의 학습 컨텐츠를 구축하는 법을 다루겠습니다 무엇을 다룰지 살짝 훑어보도록 할까요 학습자가 Swift Playgrounds에서 처음 컨텐츠를 열면 여기 우리의 친구 Byte가 보여주는 바와 같이 여러분은 학습자에게 선택적인 환영 메시지로 프로젝트를 소개할 수 있습니다 환영 메시지는 프로젝트 소스 편집기의 상단 화면의 왼쪽에 위치하고 화면의 오른쪽에는 학습 센터가 있습니다
학습 센터는 여러분의 컨텐츠를 학습자에게 설명할 교육적 텍스트나 이미지를 추가하도록 지정된 영역입니다
환영 메시지와 학습 센터에서 SwiftUI의 색상, 도형 애니메이션을 사용해 학습자에게 이 프로젝트가 신날 것임을 알립니다
학습 센터는 작업에 대한 섹션도 포함합니다 작업은 저자가 학습자에게 도움이 되도록 작성하는 코딩 목표입니다 이는 컨텐츠의 기본 구성요소입니다
학습 센터의 작업 버튼을 탭하면 교육 체계가 Swift 파일을 열고 파일의 상단에 학습 자료와 함께 카드를 렌더링합니다 이 카드는 텍스트, 이미지, 코드 스니펫을 포함한 일련의 페이지죠 이따가 Marcus가 워크스루와 실험, 두 종류의 작업을 다룰 것인데
이는 우리가 높은 수준의 교육 체계에서 제공해야 하는 것입니다 적절한 글과 작업을 통해 학습자에게 매력적인 교육 경험을 구축할 수 있습니다 우리의 컨텐츠를 만들기 전에 가이드 모듈에 대해 말씀드리겠습니다 기본적으로 swiftpm 프로젝트의 파일 구조는 모든 소스코드를 루트에 저장합니다 교육 체계의 장점을 취하도록 프로젝트를 업그레이드 하려면 파일 구조를 바꿔야 합니다 먼저 앱 모듈을 만들어야 합니다 앱 모듈이 한번 만들어지면 프로젝트의 모든 소스코드와 에셋을 그 안으로 옮겨야 합니다 이 때 Package.swift 파일은 프로젝트 루트에 남아있어야 해요
이제 가이드 모듈을 만들어야 합니다 이 모듈은 앱 모듈, Package.swift 파일과 같은 수준에 위치해야 해요 가이드 모듈 내부에는 가이드 파일이 필요합니다 이 파일은 모든 글과 학습 컨텐츠를 포함하게 됩니다 저는 가이드 파일을 이미 만들기 시작했으니 지금까지 만들어진 컨텐츠를 확인해보죠
가이드 파일은 디렉티브와 마크다운으로 구성됩니다 디렉티브는 마크다운의 확장으로 문자열이나 마크다운 요소 다른 디렉티브와 같이 더 복잡한 속성과 같은 원시 타입을 포함할 수 있습니다
디렉티브는 다른 디렉티브의 컨테이너가 될 수 있지만 우리의 교육 체계 UI 요소를 표현하기도 합니다 저는 먼저 가이드 파일에 필수적인 파일 전체를 포함하는 가이드북 디렉티브를 추가했습니다 이는 다른 모든 디렉티브의 주 컨테이너 역할을 합니다 가이드북 디렉티브의 매개변수는 제목, 아이콘, 배경 이미지 그리고 프로젝트를 열 때 가장 먼저 열리길 바라는 파일이죠 가이드북 디렉티브 아래에 환영 메시지 디렉티브를 추가했죠 환영 메시지는 선택적이며 앞서 언급한 바와 같이 학습자가 처음 프로젝트를 열 때 나타나게 됩니다 환영 메시지 디렉티브 아래에는 단계 디렉티브를 감싸는 가이드 디렉티브를 추가했습니다 가이드 디렉티브는 단계 디렉티브의 컨테이너가 되며 단계는 학습 센터와 작업에 나타난 컨텐츠에 매핑됩니다 이미지와 교육적 텍스트를 학습 센터에 추가하려면 ContentAndMedia 디렉티브를 단계 디렉티브에 포함시켜야 해요
이렇게 댄스 플로어와 친절한 환영 메시지 그리고 학습 센터를 위한 글을 추가해 파티를 시작했습니다 Marcus, 파티를 계속하고 싶은가요? 그럼요 동물들이 파티를 하기에 정말 멋진 댄스 플로어예요 이 효과가 정말 멋지긴 하지만 제 생각에는 아직 배우는 사람에겐 좀 과한 것 같아요 코드의 이해를 돕기 위해 워크스루 작업을 쓸 수 있습니다 한 페이지 짜리 워크스루로 시작해보죠 나머지를 어떻게 채울지는 나중에 보여드리겠습니다 Stephanie가 도움이 되는 환영 메시지와 가이드북의 시작을 보여드렸습니다 작업을 만드는 데 필요한 첫번째 디렉티브인 단계 디렉티브를 이미 갖고있습니다 워크스루 컨텐츠는 단계 디렉티브에 포함됩니다 단계를 만들기 위해 다른 두 디렉티브를 채워야 합니다 ContentAndMedia 디렉티브는 이미 추가했습니다 이 디렉티브는 화면 오른편의 학습 센터에 배치될 마크다운을 포함합니다 이 디렉티브의 본문은 어떤 형태의 마크다운 텍스트도 포함할 수 있죠 여기에는 여러분의 주제를 다루는 데 도움이 될 더 긴 글과 큰 이미지를 추가할 수 있습니다 ContentAndMedia 디렉티브는 Swift Playgrounds에서 이렇게 표시되죠 이 예제에서는 이 영역이 작아 보이지만 이 보기는 스크롤 보기에 포함돼 있어 아래로 더 확장될 수 있죠 따라서 이 영역에 긴 글이나 다이어그램처럼 복잡한 컨텐츠도 추가하기 좋습니다 ContentAndMeida 디렉티브를 작성한 뒤에는 두 번째로 필요한 디렉티브인 작업을 추가할 수 있습니다 작업은 TaskGroup이라는 다른 디렉티브에 추가합니다 TaskGroup은 선택적 디렉티브로 여러 작업의 집합을 한데 모으기 위해 단계 디렉티브 안에 넣을 수도 있습니다 여러 파일이나 다른 유형의 작업에서 같은 주제를 다루는 컨텐츠가 있는지 고려할 수 있습니다 TaskGroup 안에는 약간의 짧은 텍스트를 추가할 수 있습니다 이는 학습 센터의 부제목으로 보이게 됩니다
Swift Playgrpounds에서 TaskGroup은 이렇게 표시됩니다
이제 TaskGroup과 부제목이 있으니 작업 디렉티브를 추가할 수 있습니다 작업은 몇가지 매개변수를 가지는데 첫 번째 매개변수는 type입니다 이는 교육 체계에서 이 작업을 보여줄 때 어떤 UI를 생성할지 정합니다 다음으로 모든 작업은 id가 필요합니다 id는 여러분이 원하는 아무 문자열이나 될 수 있습니다 그러나 가이드의 모든 id는 중복되면 안됩니다 title 매개변수 역시 문자열입니다 id처럼 원하는 어떤 문자열도 가능한데 중복 가능한 점이 다르죠 title은 task card UI에 의해 제목으로 렌더링됩니다 마지막으로 file 매개변수는 학습자가 작업을 시작할 때 어떤 파일을 열어야 할지 학습 센터에 전달합니다 작업은 Swift Playgrounds에서 이렇게 표시됩니다 title은 버튼 안에 표시되고 워크스루 파일은 위의 목록에 나타납니다 이제 워크스루 작업을 만들었으니 첫 페이지를 추가해봅시다 페이지 디렉티브는 작업 디렉티브의 본문에 추가됩니다 그리고 다음과 같은 필수 매개변수를 가집니다 id 매개변수는 작업의 id와 비슷합니다 반드시 가이드 파일 전체에서 고유해야 합니다 title 매개변수는 작업의 title과 비슷하지만 여기서는 빈 문자열로 남기면 교육 체계에서 이 페이지를 표시할 때 작업의 title을 대신 표시합니다 페이지 안에는 ContentAndMedia 디렉티브처럼 어떠한 마크다운 텍스트도 추가할 수 있습니다 그러나 작업 보기는 학습 센터보다 훨씬 작습니다 학습자가 읽기 힘들 수 있으므로 텍스트를 짧게 유지하고 복잡한 이미지나 다이어그램 사용을 자제해야 합니다 이는 Swift Playgrounds에서 렌더링 된 워크스루의 첫 페이지죠 첫 번째 워크스루가 거의 끝나갑니다 그런데 그 전에 여러분께 지난 스크린샷에서처럼 코드를 강조하는 법을 보여드리겠습니다 이를 위해 CreatureDance.swift에 몇가지 표시를 추가해야합니다 워크스루가 보여지면 첫번째 변경자인 AnimatedScalingEffect를 강조하고 싶습니다 줄에 강조를 추가하기 위해 코드의 전후로 주석을 추가하겠습니다 /*를 이용해 여러 줄을 주석처리 합니다 주석 안에는 #-code-walkthrough(1.modifier)를 작성합니다, 괄호 안의 값은 강조하고자 하는 페이지 디렉티브의 id로 여기서는 1.modifier입니다
이제 Swift Playgrounds에서 이를 테스트해봅시다 Emoji App 프로젝트를 엽니다
프로젝트를 열면 처음에 소스 편집기가 왼쪽에 나타나고 미리보기가 오른쪽에 나타납니다 소스 편집기 위에는 환영 메시지가 나타나며 우리 친구 Byte가 하게 될 학습 컨텐츠의 개요를 설명합니다 'Learn More' 버튼을 탭하면
오른쪽의 미리보기는 학습 센터로 바뀝니다 글의 맨 위에는 ContentAndMedia 디렉티브에 쓰인 것이 표시되죠 그 아래는 TaskGroup으로 우리 워크스루의 제목이 쓰여있는 버튼이 표시됩니다 워크스루는 학습 센터에서 Byte의 친구인 Expert의 그림과 함께 버튼으로 표시됩니다
이 버튼을 탭하면 몇 가지 작업이 수행됩니다 먼저 학습 센터가 다시 미리보기로 돌아갑니다 다음으로 파일이 아직 열려있지 않다면 작업의 file 매개변수에서 특정된 파일이 소스 편집기에서 열립니다 세 번째로, 작업 보기가 소스 편집기 위에 드롭다운 됩니다 마지막으로 소스 편집기가 주석으로 표시된 코드를 강조합니다 강조된 코드가 화면에서 안보이면 소스 편집기가 스크롤을 강조가 나타나야 하는 부분까지 내려 해당 부분의 코드를 보여줘요 여기까지 Swift Playgrounds에서 워크스루를 작성하는 방법입니다 아마도 여러분들께서는 여러 페이지로 이루어진 워크스루는 어떻게 표시될지 궁금하실 것입니다 이를 위해 Xcode로 프로젝트를 열어 나머지 부분을 채워보죠
이제 Xcode에서 가이드 파일이 열렸고 이 워크스루에 몇 페이지를 더 추가해주겠습니다 보기 변경자가 무엇인지 약간 설명했었는데요 사용자 지정 보기 변경자를 만드는 법을 더 설명하고 싶습니다 더 진행해서 그 페이지를 만들겠습니다
좋습니다 이제 사용자 정의 보기 변경자에 대한 워크스루이 생겼습니다
지금이 ViewModifier 프로토콜을 설명하기 좋은 때 같네요 이렇게 학습자가 원하면 직접 그들만의 ViewModifier를 만들 수 있죠 이를 위해 TaskGroup에 또 다른 워크스루를 추가할게요
이제 워크스루들이 꽉 차게 됐습니다 iPad로 넘어가서 어떻게 보이는지 보겠습니다
프로젝트를 열 때 이제 학습 센터에 두 가지 워크스루가 나타납니다 첫 번째 워크스루를 탭해서 시작해보겠습니다
전과 같이 보기 변경자가 있는 줄이 강조됩니다 그리고 작업 보기는 이 코드가 무엇인지 드롭다운으로 나타냅니다 이제 'Next' 버튼을 탭할 수 있습니다
소스 편집기는 Modifier 구조체로 스크롤을 내리고 이 구조체가 무엇인지 설명합니다
'Next' 버튼을 탭하면 이 워크스루의 최종 페이지로 이동해 Modifier 구조체 안의 body 메소드를 상세히 설명합니다 작업 보기의 아래쪽 구석에 'Next workthrough' 버튼이 있어요
이 버튼을 탭하면 자동적으로 다음 워크스루 작업이 시작됩니다 이 기능은 더 진행할 다른 작업이 있다면 교육 체계에 의해 무료로 제공됩니다 이제 여기에서 나머지 워크스루를 탭하겠습니다
여기까지 Swift Playgrounds에서 워크스루를 만드는 방법입니다 다음으로, 학습자가 직접 코드를 추가하고 어떤 일이 생기는지 볼 수 있는 다른 종류의 작업을 만드는 방법을 보겠습니다 이 시점에서 우리는 좋은 파티를 보내고 있습니다 동물들은 빛나는 배경에서 춤을 추고 있습니다 사실상 나이트클럽처럼 보이는데 이를 조금 개선해봅시다 동물들에게 색을 추가해서 그들의 작은 클럽에서 스트로브 라이트를 받으며 춤을 추는 것 같이 만들면 좋을 듯 해요 이건 제 의견인데 여러분은 어떠신가요? 이럴 때 실험 작업을 해볼 수 있습니다 실험은 학습자들이 더 궁금한 요소나 앱을 더 특별하게 만들고 싶을 때 추가할 수 있는 선택적 코드입니다 가이드 파일에 이미 했던 방법과 같이 실험 작업을 추가할 수 있습니다 실험을 포함할 새로운 TaskGroup인 'Experiments'를 만들어주겠습니다 첫 실험 작업의 시작과 함께 부제목이 나타나게 했습니다
실험 작업과 워크스루의 첫번째 차이는 type 매개변수에 입력되는 것입니다 다른 매개변수는 워크스루 작업과 비슷하게 설정할 수 있습니다 페이지 디렉티브는 워크스루 작업에서와 똑같이 작동합니다 하지만 실험적으로 선택적 매개변수 isAddable을 추가해보죠 isAddable 매개변수는 실험 작업에서 소스 편집기로 바로 코드를 추가할 수 있게 해줍니다 isAddable이 true면 add 버튼이 코드 스니펫 옆의 배우고 있는 작업에 나타납니다 페이지 디렉티브의 코드는 마크다운 구문인 ```를 이용해 코드 블록으로 묶여야 합니다 코드 블록을 10줄 이하로 만드는 것이 좋습니다 작업 보기는 필요하면 더 긴 코드 스니펫을 보여줄 수도 있지만 학습자가 스크롤 하지 않고 볼 수 있으면 더 좋습니다 Swift Playgrounds에서 코드 보기는 이렇습니다 코드 스니펫 오른쪽에 추가 버튼이 있습니다 이는 isAddable 매개변수가 true로 설정됐기 때문입니다 여기까지 실험 작업을 만드는 데 필요한 대부분을 다뤘습니다 그런데 isAddable 매개변수를 기억하시나요? 이는 실험 작업에서 소스 편집기에 코드를 추가할 수 있게 하지만 Swift Playgrounds에 코드 어디에 스니펫을 추가할지 알려야 합니다 다시 CreatureDance.swift 파일을 봅시다 학습자가 투명도 변경자 바로 밑에 색상 변경자를 추가하길 원해서 그곳에 실험 작업 주석을 추가하겠습니다 실험 작업 주석은 한줄이므로 //로 시작합니다 그리고 #-learning-task(colors)를 입력합니다 괄호 안의 colors는 실험 작업의 id입니다 이제 실험 작업을 테스트해 볼 준비를 마쳤습니다 이번에도 제가 Stephanie와 제가 작업하는 swiftpm 프로젝트에 미리 작성해뒀습니다 확인해 봅시다 다시 학습 센터로 돌아왔습니다 이번에는 첫 번째 실험이 있는 하단 작업에 집중하겠습니다 실험은 Byte의 또 다른 친구인 Blu에 의해 교육 체계에 기록됩니다 실험 작업을 탭해보겠습니다
다음에 일어나는 일은 친숙해 보여야 합니다 작업 보기가 드롭다운 됩니다 그런데 이번에는 작업 보기가 코드 보기를 포함합니다 코드 보기의 오른 쪽에 추가 버튼이 있습니다 이 버튼을 탭하면 소스 편집기에 코드가 추가됩니다
코드가 추가됐으니 CreatureDanceView에 어떤 변화가 생겼는지 확인해보죠 파티를 시작합시다!
좋네요 이제 빛이 동물들에 부딪히는 것을 볼 수 있습니다 꽤 그루브가 있는데요 타이머를 사용해 동물들에게 수 초마다 무작위 색을 입혀 한 단계 발전시켜 보죠 이를 위해 새로운 실험을 추가해야 합니다 이 프로젝트를 다시 Xcode에 가져가 새 작업을 추가합시다 두 번째 실험을 추가하기 전에 이미 있는 실험에 페이지를 추가하는 것이 좋을 것 같습니다 학습자는 코드 블록이 추가될 때 그 코드의 이유와 역할을 잘 몰라 혼란스러울 수 있으니까요 이를 돕기 위해 코드 페이지 앞에 글과 함께 페이지를 추가할게요
이제, 두 번째 작업을 추가할 준비가 됐습니다 이번에도 학습자가 프로젝트에 그들의 코드를 넣길 바라므로 추가할 수 있는 코드 스니펫 뒤에 코드 설명 페이지를 추가할게요
여기까지 사용자 정의 보기 변경자로 할 수 있는 것들에 대해 학습자들을 가르칠 새로운 컨텐츠를 만들었습니다 Stephanie, 우리가 지금까지 만든 것을 보여줄 준비가 됐나요? 그래요 보여줍시다
우리가 만든 컨텐츠의 최종 버전을 iPad에서 열고 제 변경과 Marcus의 변경이 어떻게 합쳐지는지 보겠습니다 프로젝트를 처음 열면 환영 메시지가 나오며 동물 파티를 소개합니다 환영 메시지의 'Learn More' 버튼을 탭하면 학습 센터가 열립니다 멋집니다 학습 센터의 맨 위에는 제 설명이 쓰여있고 Marcus가 추가한 네 개의 작업이 있습니다 첫번째 워크스루를 탭해보겠습니다
Marcus가 사용자 정의 보기 변경자를 사용법 설명의 예시로 제 AnimatedScalingModifier를 사용했네요
'Next Walkthrough' 버튼을 탭하면 두번째 워크스루가 나타납니다
Marcus는 ViewModifier 프로토콜로 프로토콜의 작동 방법을 설명했죠 두 번째 워크스루가 끝난 뒤에 'Done' 버튼을 탭하면 첫 번째 실험으로 넘어갑니다
'Dancing in the Strobe Light'은 제가 colorMultiply 변경자가 포함된 코드 스니펫을 추가해서 동물에 색을 입힐 수 있음을 알려줍니다 코드 스니펫을 추가하기 전에 이 댄스 파티가 어땠는지 상기해봅시다
좋아요, 괜찮네요 추가하기 버튼을 탭해서 코드 스니펫을 추가하고 'Start the Party' 버튼을 다시 탭해 바뀐 것을 봅시다
좋네요, 동물들의 색이 바뀝니다 이 실험을 이제 마치고 마지막으로 넘어가겠습니다
Switch It Up 실험 작업은 탭 제스처나 시간에 따라 동물의 색을 바꾼다고 합니다 코드 스니펫을 추가하고 다시 'Start the Party' 버튼을 탭해요
이제 제가 동물들을 탭하면 색이 바뀝니다 좋네요 마지막 작업을 완료하고 다시 학습 센터로 돌아갑니다
이제 학습 센터의 모든 작업들이 완료됨으로 표시됐습니다 즉, 이 샘플을 완료했습니다
여기까지 Swift Playgrounds 4의 새로운 컨텐츠 기능의 장점을 활용하는 방법을 다뤘습니다 오늘의 세션이 즐거우셨길 바라며 여러분들이 어떤 종류의 실험을 만들어낼지 정말 기대됩니다 다른 Swift Playgrounds 세션인 'Swift Playgrounds에서 여러분의 첫 앱을 만들기'도 잊지 말고 확인해주세요 남은 WWDC를 즐기시길 바랍니다 괜찮으시다면, 저희는 가야할 파티가 있어 먼저 가볼게요
-
-
1:27 - Dance Floor
let numOfTiles = 100 let squareLength = 150.0 // Dance floor ForEach(0 ..< numOfTiles, id: \.self) { index in let i: CGFloat = CGFloat(index / 10) let j: CGFloat = CGFloat(index % 10) let x = (squareLength * i) - (squareLength) let y = (squareLength * j) - (squareLength * 2) Rectangle() .frame(width: squareLength, height: squareLength) .border(.black, width: 3) .position(x: x, y: y) .randomizedColorEffect(startAnimation: startParty) } .blur(radius: 15) .opacity(startParty ? 1.0 : 0.0)
-
1:47 - Dance
ForEach(data.creatures) { creature in Text(creature.emoji) .resizableFont() .animatedScalingEffect(startAnimation: startParty) .randomizedOffsetEffect(startAnimation: startParty, x: midX * 0.6, y: midY * 0.6) .animatedRotationEffect(startAnimation: startParty) .opacity(startParty ? 1.0 : 0.0) }
-
2:08 - Disco Ball
Text("🪩") .resizableFont() .animatedRotationEffect(startAnimation: startParty) .opacity(startParty ? 1 : 0)
-
5:12 - Guidebook Directive
@GuideBook(title: "Creature Party!", icon: icon.png, background: background.png, firstFile: CreatureDance.swift) { }
-
5:28 - Welcome Message
@WelcomeMessage(title: "Welcome to Creature Party!") { In Creature Party, you'll take this app of dancing creatures to the next level with the help of colors, shapes, animations, and plenty of emoji! }
-
5:37 - Guide and Step Directives
@Guide { @Step(title: "Pump up the jams") { } } }
-
5:53 - Content and Media Directive
@ContentAndMedia { Tonight, the creatures are gonna party like it's 2022. 🐙💃🦝🕺🦦 }
-
7:15 - Task Group Directive
@TaskGroup(title: "Walkthroughs") { Here are the walkthroughs! These will help explain all of the new code. }
-
7:57 - First Walkthrough Task
@Task(type: walkthrough, id: "partyMode", title: "Setting up the Party", file: CreatureDance.swift) { }
-
8:44 - First Walkthrough Page
@Page(id: "1.modifier", title: "") { This is a [view modifier](https://developer.apple.com/documentation/swiftui/viewmodifier). Modifiers let you create unique versions of a view in SwiftUI. }
-
9:48 - Walkthrough Highlight
ForEach(data.creatures) { creature in Text(creature.emoji) .resizableFont() /*#-code-walkthrough(1.modifier)*/ .animatedScalingEffect(startAnimation: startParty) /*#-code-walkthrough(1.modifier)*/ .randomizedOffsetEffect(startAnimation: startParty, x: midX * 0.6, y: midY * 0.6) .animatedRotationEffect(startAnimation: startParty) .opacity(startParty ? 1.0 : 0.0) }
-
11:56 - First Walkthrough extra pages
@Page(id: "1.struct", title: "") { Custom view modifiers are structures that contain code for explaining how to modify whatever view the given modifier is attached to. } @Page(id: "1.body", title: "") { The body method allows you to add custom view modifications. For example, here you're adding a scaling animation that grows and shrinks the `Creature` over a certain period of time. }
-
12:18 - Second Walkthrough Task
@Task(type: walkthrough, id: "protocol", title: "A Little More on Protocols", file: CreatureDance.swift) { @Page(id: "2.protocol", title: "") { All custom view modifiers implement the `ViewModifier` protocol. } @Page(id: "2.body", title: "") { The `ViewModifier` protocol requires all structures that implement it to write the `body(content:)` method. } @Page(id: "2.usage", title: "") { After you've written content for your `body(content:)` method, you can use it on any view you want. Here you'll use it on each `Creature` to add a rotation animation. } }
-
14:21 - First Experiment Task
@TaskGroup(title: "Experiments") { Time to set this party off! You can use experiments to add some extra pazazz to the dance floor. @Task(type: experiment, id: "colors", title: "Dancing in the Strobe Light", file: CreatureDance.swift) { } }
-
14:48 - First Experiment Page
@Page(id: "3.code", title: "", isAddable: true) { ``` .colorMultiply(creatureColor) ``` }
-
15:55 - Experiment Task Comment
ForEach(data.creatures) { creature in Text(creature.emoji) .resizableFont() /*#-code-walkthrough(1.modifier)*/ .animatedScalingEffect(startAnimation: startParty) /*#-code-walkthrough(1.modifier)*/ .randomizedOffsetEffect(startAnimation: startParty, x: midX * 0.6, y: midY * 0.6) /*#-code-walkthrough(2.usage)*/ .animatedRotationEffect(startAnimation: startParty) /*#-code-walkthrough(2.usage)*/ .opacity(startParty ? 1.0 : 0.0) //#-learning-task(colors) }
-
17:42 - Experiment Text
@Page(id: "3.lights", title: "") { Next, add some colors to the creatures so it looks like they're dancing under the lights! }
-
17:55 - Second Experiment Task
@Task(type: experiment, id: "timer", title: "Switch it Up", file: CreatureDance.swift) { @Page(id: "4.lights", title: "") { Now that you have some colors, you can add some code to change the color of the creatures using a timer. Let's add one! } @Page(id: "4.code", title: "", isAddable: true) { ``` .onTapGesture { if let timer = timer { timer.invalidate() self.timer = nil } else { creatureColor = Color.randomColor timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true, block: { timer in creatureColor = Color.randomColor }) } } ``` } }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.