Final exam
퀴즈 기록
- Rounded rectangles and capsules are different shapes.
- Properties wrapped in @Environment must have a value before the view is shown. If their view is shown without the value right, your app crashes.
- @Model only works with classes.
- When creating a custom alignment guide we must provide a default value.This will be used if we don't attach the alignmentGuide() modifier to a view.
- SwiftUI's views work great as @State properties
- Although text fields use strings by default, we can also bind them to numbers.
- This protocol has only one requirement: a property called id that should be unique.
- The NavigationStack view lets us show new views and also place text at the top of the screen.
- The sequenced(before:) modifier lets us create chains of gestures. The first gesture must succeed in order for the second to be recognized.
Swift's arrays use generics. This means we make arrays of strings or integers – we can't make an untyped array.
- If we use a string binding with the navigationTitle() modifier, that title is editable. This is true, but only when the navigation bar is using inline display mode.
- The coordinateSpace() modifier lets us create a custom coordinate space.
- A view is always and exactly the same size as its body. When we apply size rules to a view, we are just applying those rules to whatever is in its body.
- contentShape() allows us to control the tap area for a view. This is particularly useful for stacks that have layout "holes".
- Custom view modifiers must conform to the ViewModifier protocol. This has one requirement: a body() method that returns some View.
- View modifiers always return a new instance of a struct, and may create lots of new views if needed.
- Swift macros rewrite our code at build time. This lets them inject all sorts of extra functionality.
- There is no limit to the number of views that can share a single environment object.
- When a URLSession download completes, it will send back the downloaded data plus any additional metadata. These values are passed back in a tuple, and you can use
_
to ignore either of them.
- Parents must always respect the size requested by their children.
- Without further information, most parents place their child views in the center.
- Text views automatically fit the size required to display all their lines. If you want them to be larger you should use padding or a custom frame.
- We can ask the user to enter multiple lines of text using TextEditor. You can also pass an axis to TextField, to make it start small then grow over time.
- All SwiftUI views must have a body property. This body must always return precisely one view. That view might contain more views inside it, but you still need to return precisely one from the computed property.
- The InsettableShape protocol builds on the Shape protocol. This means we don't need to make our custom shapes conform to both.
- SwiftUI has five built-in coordinate spaces. SwiftUI only has two built-in coordinate spaces: global and local.
- We can create a new task at any time using Task { … }. This is the best way to run an asynchronous function from a synchronous one, such as a button action.
- Result can be used with throwing functions, but it doesn't need to be.
- onDelete(perform:) cannot be attached directly to a List view. We must attach onDelete(perform:) to a ForEach view instead.
- We can receive values from a Combine publisher using onReceive(). This can be a Timer, a notification from Notification Center, or something else.
- Swift's Result type can contain either success or failure, but not both. This lets us reduce complexity in our code by eliminating impossible program states.
- You don't need the macro unless you specifically want SwiftUI to watch the object for changes.
- Materials let us apply a frosted glass-style blur effect for our view backgrounds. When combined with foregroundStyle(.secondary) this helps ensure UI elements stand out well from the background.
- As long as your app has iCloud enabled under its list of capabilities, you might need no code changes at all.
- Writing data atomically means that iOS writes to a temporary file then performs a rename. This stops another piece of code from reading the file part-way through a write.
- In SwiftData, we can use @Relationship to control the delete rule for our data models.
- The @Bindable property wrapper is very different from the @Binding property wrapper. Use @Bindable when you want to work with a object that uses the @Observable macro, and use @Binding when you want to observe a simple value such as an integer or a string.
- The @State property wrapper places our properties inside a State struct. Behind the scenes, this is actually similar to how optionals work.
- We can detect when a sheet is closed by setting its onDismiss parameter.
- When we import a Core ML model into Xcode, it will automatically generate a Swift class for us to use. This lets us create an instance of the model and request a prediction in only two lines of code.
- Colors are views in SwiftUI. This allows us to use them directly inside stacks.
- When allowsHitTesting() is false, a view cannot be tapped. Any taps simply pass through to whatever is stacked below.
- SwiftUI's previews aren't included in our app if we send it to the App Store. Swift automatically strips out the previews; they are just there to help us design our UI.

후기

올해 포스텍 애플 디벨로퍼에서 ios 개발을 계기로 swiftui 공부를 위 강의와 함께 시작했다. 주변 러너가 추천해주시고 여럿이서 시작한 레이스를 어떻게 뚝심있게 해냈다.
swiftui를 아예 몰랐었는데, 덕분에 이젠 내가 '모르는 것'을 알고 얕고 넓은 분야에서 swiftui를 활용해봤고 다시 활용해볼 수 있다. 추가로 관심이 없다면 지나쳤을 수도 있는 Accessibility, 다른 OS의 경험까지 할 수 있는 것이 되었다.
대부분의 챌린지는 제시하는 대로 완료했고, 또는 나아가 내가 변경하기도 해봤다. 물론 아직 해결하지 못한 것이나 이해하지 못한 것들도 있었는데 이는 차차 해결해야겠다.
야호! 앞으론 챌린지 형태로 배우고 싶은 걸 위주로 나아가 봐야지.