SwiftUI changes in Xcode 11 Beta 4

⋅ 3 min read ⋅ SwiftUI iOS beta

Table of Contents

iOS & iPadOS 13 Beta 4 just released today, let's see some highlight changes for SwiftUI, you can check the rest here.

color -> foregroundColor

The color(_:) modifier for Text is renamed foregroundColor(_:).

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

relativeWidth/Height/Size are gone :(

The relativeWidth(_:), relativeHeight(_:), and relativeSize(width:height:) modifiers are deprecated. Apple suggests us to use other modifiers like frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:) instead.

I was shocked when these methods are gone, but the situation might not be that bad since I didn't use it that much and in my experienced designers never think in relative width/height, they always think padding and fixed size which already provided in SwiftUI. This is still in beta Apple might decide to bring it back if community ask for it.

BindableObject protocol

The BindableObject protocol’s requirement is now willChange instead of didChange, and should now be sent before the object changes rather than after it changes.

DatePicker deprecated initializers

Initializers with minimumDate and maximumDate are gone. Now we initialized it with ClosedRange, PartialRangeThrough, and PartialRangeFrom.

We use PartialRangeFrom for minimumDate.

DatePicker("Minimum Date",
selection: $selectedDate,
in: Date()...,
displayedComponents: [.date])

We use PartialRangeThrough for maximumDate.

DatePicker("Maximum Date",
selection: $selectedDate,
in: ...Date(),
displayedComponents: [.date])

If you want to enforce both minimumDate and maximumDate use ClosedRange

@State var selectedDate = Date()

var dateClosedRange: ClosedRange<Date> {
let min = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
let max = Calendar.current.date(byAdding: .day, value: 1, to: Date())!
return min...max
}

DatePicker(
selection: $selectedDate,
in: dateClosedRange,
displayedComponents: [.hourAndMinute, .date],
label: { Text("Due Date") }
)

Collection protocol

The identified(by:) method on the Collection protocol is deprecated in favor of dedicated List's init(_:id:selection:rowContent:) and ForEach's init(_:id:content:) initializers.

So this code

let users = ["John", "Alice", "Bob"]

var body: some View {
List(users.identified(by: \.self)) { user in
NavigationLink(destination: Text("Detail for \(user)")) {
Text(user)
}
}.navigationBarTitle("List Example")
}

Would become something like

let users = ["John", "Alice", "Bob"]

var body: some View {
List(users, id: \.self) { user in
NavigationLink(destination: Text("Detail for \(user)")) {
Text(user)
}
}.navigationBarTitle("List Example")
}

Presentation

Alert, Modal, and ActionSheet have different syntax in the previous beta. This update brings consistency to these presentation methods. For keeping everything consistent, PresentationLink is deprecated.

struct PresentationExample: View {
@State var isPresented = false
@State var isActionSheet = false
@State var isAlert = false

var actionSheet: ActionSheet {
ActionSheet(title: Text("Action"),
message: Text("Description"),
buttons: [
.default(Text("OK"), onTrigger: {

}),
.destructive(Text("Delete"), onTrigger: {

})
]
)
}

var alert: Alert {
Alert(title: Text("Error"),
message: Text("Error Reason"),
dismissButton: .default(Text("OK"))
)
}

var modal: some View {
Text("Modal")
}

var body: some View {
VStack {
Button("Modal") {
self.isPresented = true
}
Button("Action Sheet") {
self.isActionSheet = true
}
Button("Alert Sheet") {
self.isAlert = true
}
}.sheet(isPresented: $isPresented, content: {
self.modal
})
.actionSheet(isPresented: $isActionSheet, content: {
actionSheet
}).alert(isPresented: $isAlert, content: {
alert
})

}
}

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

References

You can check out my compiled cheat sheet at fuckingswiftui.com or goshdarnswiftui.com if you want more work-friendly.


Read more article about SwiftUI, iOS, beta, or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Buy me a coffee Tweet Share
Previous
Better dependency injection for Storyboards in iOS13

Say goodbye to optional properties in your view controllers. In iOS13, you can inject those properties at a time of view controller creation.

Next
How to use SwiftUI in UIKit

Using SwiftUI as UIView and UIViewController

← Home