Minimum changes for Xcode 11 beta 5

This commit is contained in:
John Holdsworth
2019-07-31 14:11:25 +01:00
parent 7af0a711da
commit a36ff1b7ca
48 changed files with 209 additions and 114 deletions

View File

@@ -89,7 +89,7 @@ struct BlockView : View {
.foregroundColor(colorPair.1) .foregroundColor(colorPair.1)
.id(numberText) .id(numberText)
.transition(AnyTransition.scale(scale: 0.5, anchor: .center).combined(with: .opacity)) .transition(AnyTransition.scale(scale: 0.5, anchor: .center).combined(with: .opacity))
.animation(.fluidSpring()) // .animation(.fluidSpring())
} }
.clipped() .clipped()
.cornerRadius(6) .cornerRadius(6)
@@ -104,7 +104,7 @@ struct BlockView_Previews : PreviewProvider {
static var previews: some View { static var previews: some View {
Group { Group {
ForEach((1...11).map { Int(pow(2, Double($0))) }) { i in ForEach((1...11).map { Int(pow(2.0, Double($0))) }, id: \.self) { i in
BlockView(number: i) BlockView(number: i)
.previewLayout(.sizeThatFits) .previewLayout(.sizeThatFits)
} }

View File

@@ -23,13 +23,13 @@ struct HikeDetail: View {
.frame(height: 200, alignment: .center) .frame(height: 200, alignment: .center)
HStack(spacing: 25) { HStack(spacing: 25) {
ForEach(buttons.identified(by: \.0)) { value in ForEach(buttons, id: \.0) { value in
Button(action: { Button(action: {
self.dataToShow = value.1 self.dataToShow = value.1
}) { }) {
Text(verbatim: value.0) Text(verbatim: value.0)
.font(.system(size: 15)) .font(.system(size: 15))
.color(value.1 == self.dataToShow .foregroundColor(value.1 == self.dataToShow
? Color.gray ? Color.gray
: Color.accentColor) : Color.accentColor)
.animation(nil) .animation(nil)

View File

@@ -51,7 +51,7 @@ final class ImageStore {
?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale)
images.values[index][size] = sizedImage images.values[index][size] = sizedImage
return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name))
} }
fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index {

View File

@@ -9,20 +9,20 @@ import SwiftUI
struct GraphCapsule: View { struct GraphCapsule: View {
var index: Int var index: Int
var height: Length var height: CGFloat
var range: Range<Double> var range: Range<Double>
var overallRange: Range<Double> var overallRange: Range<Double>
var heightRatio: Length { var heightRatio: CGFloat {
max(Length(magnitude(of: range) / magnitude(of: overallRange)), 0.15) max(CGFloat(magnitude(of: range) / magnitude(of: overallRange)), 0.15)
} }
var offsetRatio: Length { var offsetRatio: CGFloat {
Length((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) CGFloat((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange))
} }
var animation: Animation { var animation: Animation {
Animation.spring(initialVelocity: 5) Animation.spring()
.speed(2) .speed(2)
.delay(0.03 * Double(index)) .delay(0.03 * Double(index))
} }

View File

@@ -40,7 +40,7 @@ struct HikeGraph: View {
let data = hike.observations let data = hike.observations
let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] })
let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()!
let heightRatio = 1 - Length(maxMagnitude / magnitude(of: overallRange)) let heightRatio = 1 - CGFloat(maxMagnitude / magnitude(of: overallRange))
return GeometryReader { proxy in return GeometryReader { proxy in
HStack(alignment: .bottom, spacing: proxy.size.width / 120) { HStack(alignment: .bottom, spacing: proxy.size.width / 120) {

View File

@@ -49,7 +49,7 @@ final class ImageStore {
?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale)
images.values[index][size] = sizedImage images.values[index][size] = sizedImage
return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name))
} }
fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index {

View File

@@ -8,9 +8,7 @@ struct SearchUserBar: View {
ZStack { ZStack {
HStack { HStack {
TextField( TextField(
$text, "Search User", text: $text
placeholder: Text("Search User")
.foregroundColor(Color.gray)
) )
.padding([.leading, .trailing], 8) .padding([.leading, .trailing], 8)
.frame(height: 32) .frame(height: 32)

View File

@@ -54,7 +54,7 @@ final class SearchUserViewModel: BindableObject {
.replaceError(with: nil) .replaceError(with: nil)
.eraseToAnyPublisher() .eraseToAnyPublisher()
.receive(on: DispatchQueue.main) .receive(on: DispatchQueue.main)
.receive(subscriber: Subscribers.Sink<UIImage?, Never> { [weak self] image in .receive(subscriber: Subscribers.Sink<UIImage?, Never>(receiveCompletion: {_ in}) { [weak self] image in
self?.userImages[user] = image self?.userImages[user] = image
}) })
} }

View File

@@ -8,6 +8,8 @@ A view showing featured landmarks above a list of all of the landmarks.
import SwiftUI import SwiftUI
struct CategoryHome: View { struct CategoryHome: View {
@State private var isProfilePresented = false
var categories: [String: [Landmark]] { var categories: [String: [Landmark]] {
.init( .init(
grouping: landmarkData, grouping: landmarkData,
@@ -39,13 +41,16 @@ struct CategoryHome: View {
} }
.navigationBarTitle(Text("Featured")) .navigationBarTitle(Text("Featured"))
.navigationBarItems(trailing: .navigationBarItems(trailing:
PresentationLink(destination: Text("User Profile")) { Button(action: {
self.isProfilePresented = true
}) {
Image(systemName: "person.crop.circle") Image(systemName: "person.crop.circle")
.imageScale(.large) .imageScale(.large)
.accessibility(label: Text("User Profile")) .accessibility(label: Text("User Profile"))
.padding() .padding()
} }
) ).sheet(isPresented: $isProfilePresented,
content: { Text("User Profile") })
} }
} }
} }

View File

@@ -51,7 +51,7 @@ final class ImageStore {
?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale)
images.values[index][size] = sizedImage images.values[index][size] = sizedImage
return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name))
} }
fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index {

View File

@@ -9,20 +9,20 @@ import SwiftUI
struct GraphCapsule: View { struct GraphCapsule: View {
var index: Int var index: Int
var height: Length var height: CGFloat
var range: Range<Double> var range: Range<Double>
var overallRange: Range<Double> var overallRange: Range<Double>
var heightRatio: Length { var heightRatio: CGFloat {
max(Length(magnitude(of: range) / magnitude(of: overallRange)), 0.15) max(CGFloat(magnitude(of: range) / magnitude(of: overallRange)), 0.15)
} }
var offsetRatio: Length { var offsetRatio: CGFloat {
Length((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) CGFloat((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange))
} }
var animation: Animation { var animation: Animation {
Animation.spring(initialVelocity: 5) Animation.spring()
.speed(2) .speed(2)
.delay(0.03 * Double(index)) .delay(0.03 * Double(index))
} }

View File

@@ -40,7 +40,7 @@ struct HikeGraph: View {
let data = hike.observations let data = hike.observations
let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] })
let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()!
let heightRatio = 1 - Length(maxMagnitude / magnitude(of: overallRange)) let heightRatio = 1 - CGFloat(maxMagnitude / magnitude(of: overallRange))
return GeometryReader { proxy in return GeometryReader { proxy in
HStack(alignment: .bottom, spacing: proxy.size.width / 120) { HStack(alignment: .bottom, spacing: proxy.size.width / 120) {

View File

@@ -50,7 +50,7 @@ struct ConverterView : View {
} }
Spacer() Spacer()
// Amount and conversion // Amount and conversion
TextField($baseAmount, placeholder: Text("1.0"), onCommit: { TextField("1.0", text: $baseAmount, onCommit: {
// TODO: update all currencies on the following list // TODO: update all currencies on the following list
}).foregroundColor(.white) }).foregroundColor(.white)
.background( .background(

View File

@@ -49,7 +49,7 @@ final class ImageStore {
?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale)
images.values[index][size] = sizedImage images.values[index][size] = sizedImage
return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name))
} }
fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index {

View File

@@ -22,8 +22,7 @@ struct TaskEditView: View {
let inset = EdgeInsets(top: -8, leading: -10, bottom: -7, trailing: -10) let inset = EdgeInsets(top: -8, leading: -10, bottom: -7, trailing: -10)
return VStack(alignment: .leading, spacing: 0) { return VStack(alignment: .leading, spacing: 0) {
TextField( TextField(
self.draftTitle.binding, "Enter New Title...", text: self.draftTitle.binding,
placeholder: Text("Enter New Title..."),
onEditingChanged: { _ in self.updateTask() }, onEditingChanged: { _ in self.updateTask() },
onCommit: {} onCommit: {}
) )

View File

@@ -16,7 +16,7 @@ struct TaskListView: View {
var body: some View { var body: some View {
NavigationView { NavigationView {
List { List {
TextField($draftTitle, placeholder: Text("Create a New Task..."), onCommit: self.createTask) TextField("Create a New Task...", text: $draftTitle, onCommit: self.createTask)
ForEach(self.userData.tasks) { task in ForEach(self.userData.tasks) { task in
TaskItemView(task: task, isEditing: self.$isEditing) TaskItemView(task: task, isEditing: self.$isEditing)
} }

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1100"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "EDDF069D22A6C61C00B23D44"
BuildableName = "GitHubSearchWithSwiftUI.app"
BlueprintName = "GitHubSearchWithSwiftUI"
ReferencedContainer = "container:GitHubSearchWithSwiftUI.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<TestPlans>
</TestPlans>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "EDDF069D22A6C61C00B23D44"
BuildableName = "GitHubSearchWithSwiftUI.app"
BlueprintName = "GitHubSearchWithSwiftUI"
ReferencedContainer = "container:GitHubSearchWithSwiftUI.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "EDDF069D22A6C61C00B23D44"
BuildableName = "GitHubSearchWithSwiftUI.app"
BlueprintName = "GitHubSearchWithSwiftUI"
ReferencedContainer = "container:GitHubSearchWithSwiftUI.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -20,8 +20,7 @@ struct RepositoryListView : View {
VStack { VStack {
HStack { HStack {
TextField($viewModel.text, TextField("Search repositories...", text: $viewModel.text,
placeholder: Text("Search reposipories..."),
onCommit: { self.viewModel.search() }) onCommit: { self.viewModel.search() })
.frame(height: 40) .frame(height: 40)
.padding(EdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8)) .padding(EdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8))
@@ -43,7 +42,7 @@ struct RepositoryListView : View {
.lineLimit(nil) .lineLimit(nil)
.multilineTextAlignment(.center) .multilineTextAlignment(.center)
ForEach(viewModel.repositories.identified(by: \.id)) { repository in ForEach(viewModel.repositories, id: \.id) { repository in
NavigationLink(destination: NavigationLink(destination:
WebView(url: repository.htmlUrl) WebView(url: repository.htmlUrl)

View File

@@ -49,7 +49,7 @@ final class ImageStore {
?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale)
images.values[index][size] = sizedImage images.values[index][size] = sizedImage
return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name))
} }
fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index {

View File

@@ -11,6 +11,7 @@ import AVKit
import CoreLocation import CoreLocation
struct ContentView : View { struct ContentView : View {
@State private var isCameraPresented = false
var instaPhotos: [InstaPhoto] var instaPhotos: [InstaPhoto]
var body: some View { var body: some View {
@@ -19,7 +20,17 @@ struct ContentView : View {
ForEach(instaPhotos, id: \.id) { ForEach(instaPhotos, id: \.id) {
ImageCell(photo: $0) ImageCell(photo: $0)
} }
}.navigationBarTitle("WWDC").navigationBarItems(trailing: PresentationLink("Camera", destination: CameraView())) }.navigationBarTitle("WWDC").navigationBarItems(trailing:
Button(action: {
self.isCameraPresented = true
}) {
Image(systemName: "person.crop.circle")
.imageScale(.large)
.accessibility(label: Text("User Profile"))
.padding()
}
).sheet(isPresented: $isCameraPresented,
content: { CameraView() })
} }
} }

View File

@@ -11,10 +11,11 @@ struct HikeBadge: View {
var name: String var name: String
var body: some View { var body: some View {
VStack(alignment: .center) { VStack(alignment: .center) {
Badge() // crashes in Beta 5
.frame(width: 300, height: 300) // Badge()
.scaleEffect(1.0 / 3.0) // .frame(width: 300, height: 300)
.frame(width: 100, height: 100) // .scaleEffect(1.0 / 3.0)
// .frame(width: 100, height: 100)
Text(name) Text(name)
.font(.caption) .font(.caption)
.accessibility(label: Text("Badge for \(name).")) .accessibility(label: Text("Badge for \(name)."))

View File

@@ -8,6 +8,8 @@ A view showing featured landmarks above a list of all of the landmarks.
import SwiftUI import SwiftUI
struct CategoryHome: View { struct CategoryHome: View {
@State private var isProfilePresented = false
var categories: [String: [Landmark]] { var categories: [String: [Landmark]] {
.init( .init(
grouping: landmarkData, grouping: landmarkData,
@@ -39,13 +41,16 @@ struct CategoryHome: View {
} }
.navigationBarTitle(Text("Featured")) .navigationBarTitle(Text("Featured"))
.navigationBarItems(trailing: .navigationBarItems(trailing:
PresentationLink(destination: ProfileHost()) { Button(action: {
self.isProfilePresented = true
}) {
Image(systemName: "person.crop.circle") Image(systemName: "person.crop.circle")
.imageScale(.large) .imageScale(.large)
.accessibility(label: Text("User Profile")) .accessibility(label: Text("User Profile"))
.padding() .padding()
} }
) ).sheet(isPresented: $isProfilePresented,
content: { ProfileHost().environmentObject(UserData()) })
} }
} }
} }

View File

@@ -52,7 +52,7 @@ final class ImageStore {
?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale)
images.values[index][size] = sizedImage images.values[index][size] = sizedImage
return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name))
} }
static func loadImage(name: String) -> CGImage { static func loadImage(name: String) -> CGImage {

View File

@@ -15,7 +15,7 @@ struct ProfileEditor: View {
HStack { HStack {
Text("Username").bold() Text("Username").bold()
Divider() Divider()
TextField($profile.username) TextField("", text: $profile.username)
} }
Toggle(isOn: $profile.prefersNotifications) { Toggle(isOn: $profile.prefersNotifications) {
@@ -25,20 +25,19 @@ struct ProfileEditor: View {
VStack(alignment: .leading, spacing: 20) { VStack(alignment: .leading, spacing: 20) {
Text("Seasonal Photo").bold() Text("Seasonal Photo").bold()
SegmentedControl(selection: $profile.seasonalPhoto) { Picker("", selection: $profile.seasonalPhoto) {
ForEach(Profile.Season.allCases.identified(by: \.self)) { season in ForEach(Profile.Season.allCases, id: \.self) { season in
Text(season.rawValue).tag(season) Text(season.rawValue).tag(season)
} }
} }.pickerStyle(SegmentedPickerStyle())
} }
.padding(.top) .padding(.top)
VStack(alignment: .leading, spacing: 20) { VStack(alignment: .leading, spacing: 20) {
Text("Goal Date").bold() Text("Goal Date").bold()
DatePicker( DatePicker(
$profile.goalDate, "", selection: $profile.goalDate,
minimumDate: Calendar.current.date(byAdding: .year, value: -1, to: profile.goalDate), in: Calendar.current.date(byAdding: .year, value: -1, to: profile.goalDate)! ... Calendar.current.date(byAdding: .year, value: 1, to: profile.goalDate)!,
maximumDate: Calendar.current.date(byAdding: .year, value: 1, to: profile.goalDate),
displayedComponents: .date displayedComponents: .date
) )
} }

View File

@@ -17,7 +17,7 @@ struct ProfileHost: View {
HStack { HStack {
if self.mode?.value == .active { if self.mode?.value == .active {
Button(action: { Button(action: {
self.profile = self.draftProfile self.draftProfile = self.profile
self.mode?.animation().value = .inactive self.mode?.animation().value = .inactive
}) { }) {
Text("Done") Text("Done")
@@ -33,7 +33,7 @@ struct ProfileHost: View {
} else { } else {
ProfileEditor(profile: $draftProfile) ProfileEditor(profile: $draftProfile)
.onDisappear { .onDisappear {
self.draftProfile = self.profile self.profile = self.draftProfile
} }
} }
} }

View File

@@ -22,7 +22,7 @@ struct ProfileSummary: View {
.bold() .bold()
.font(.title) .font(.title)
Text("Notifications: \(self.profile.prefersNotifications ? "On": "Off" )") Text("Notifications: \(self.profile.prefersNotifications ? "Onn": "Off" )")
Text("Seasonal Photos: \(self.profile.seasonalPhoto.rawValue)") Text("Seasonal Photos: \(self.profile.seasonalPhoto.rawValue)")
@@ -37,7 +37,7 @@ struct ProfileSummary: View {
HikeBadge(name: "Earth Day") HikeBadge(name: "Earth Day")
.hueRotation(Angle(degrees: 90)) .hueRotation(Angle(degrees: 90))
HikeBadge(name: "Tenth Hike") HikeBadge(name: "Tenth Hike")
.grayscale(0.5) .grayscale(0.5)
.hueRotation(Angle(degrees: 45)) .hueRotation(Angle(degrees: 45))

View File

@@ -9,20 +9,20 @@ import SwiftUI
struct GraphCapsule: View { struct GraphCapsule: View {
var index: Int var index: Int
var height: Length var height: CGFloat
var range: Range<Double> var range: Range<Double>
var overallRange: Range<Double> var overallRange: Range<Double>
var heightRatio: Length { var heightRatio: CGFloat {
max(Length(magnitude(of: range) / magnitude(of: overallRange)), 0.15) max(CGFloat(magnitude(of: range) / magnitude(of: overallRange)), 0.15)
} }
var offsetRatio: Length { var offsetRatio: CGFloat {
Length((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) CGFloat((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange))
} }
var animation: Animation { var animation: Animation {
Animation.spring(initialVelocity: 5) Animation.spring()
.speed(2) .speed(2)
.delay(0.03 * Double(index)) .delay(0.03 * Double(index))
} }

View File

@@ -40,7 +40,7 @@ struct HikeGraph: View {
let data = hike.observations let data = hike.observations
let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] })
let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()!
let heightRatio = 1 - Length(maxMagnitude / magnitude(of: overallRange)) let heightRatio = 1 - CGFloat(maxMagnitude / magnitude(of: overallRange))
return GeometryReader { proxy in return GeometryReader { proxy in
HStack(alignment: .bottom, spacing: proxy.size.width / 120) { HStack(alignment: .bottom, spacing: proxy.size.width / 120) {

View File

@@ -70,7 +70,7 @@ final class ImageStore {
?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale)
images.values[index][size] = sizedImage images.values[index][size] = sizedImage
return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name))
} }
fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index {

View File

@@ -17,7 +17,7 @@ struct ContentView : View {
var body: some View { var body: some View {
List { List {
ForEach(state.moviesState.popular) { id in ForEach(state.moviesState.popular, id: \.self) { id in
Text(self.state.moviesState.movies[id]?.original_title ?? "No title") Text(self.state.moviesState.movies[id]?.original_title ?? "No title")
} }
} }

View File

@@ -15,9 +15,9 @@ struct TabbarView : View {
var body: some View { var body: some View {
TabbedView(selection: $selectedIndex) { TabbedView(selection: $selectedIndex) {
UsersListView() UsersListView()
.tabItemLabel(Text("Users")) .tabItem({ Text("Users") })
MapView() MapView()
.tabItemLabel(Text("Map")) .tabItem({ Text("Map") })
} }
} }
} }

View File

@@ -13,15 +13,6 @@ struct UserDetailView : View {
@EnvironmentObject var state: AppState @EnvironmentObject var state: AppState
let userId: Int let userId: Int
var editModal: Modal {
let user = state.usersState.users[userId]
return Modal(UserEditForm(userId: user.id, saveHandler: { saved in
self.state.dispatch(action: UserActions.stopEditUser)
}).environmentObject(state)) {
self.state.dispatch(action: UserActions.stopEditUser)
}
}
var body: some View { var body: some View {
let user = state.usersState.users[userId] let user = state.usersState.users[userId]
return VStack { return VStack {
@@ -36,7 +27,11 @@ struct UserDetailView : View {
}) { }) {
Text("Edit user") Text("Edit user")
} }
.presentation(self.state.usersState.isEditingUser ? self.editModal : nil)) .sheet(isPresented: $state.usersState.isEditingUser) {
UserEditForm(userId: user.id, saveHandler: { saved in
self.state.dispatch(action: UserActions.stopEditUser)
})
})
} }
} }

View File

@@ -24,11 +24,11 @@
return NavigationView { return NavigationView {
VStack(alignment: .leading, spacing: 10) { VStack(alignment: .leading, spacing: 10) {
Text("User name") Text("User name")
TextField($newUserName, placeholder: Text("New name")) TextField("New name", text: $newUserName)
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
Divider() Divider()
Text("Username") Text("Username")
TextField($newUserUsername, placeholder: Text("New username")) TextField("New username", text: $newUserUsername)
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
}.padding(16) }.padding(16)
Button(action: save) { Button(action: save) {

View File

@@ -15,7 +15,7 @@ struct Badge : View {
var animation: Animation { var animation: Animation {
Animation Animation
.spring(initialVelocity: 5) .spring()
.speed(2) .speed(2)
} }

View File

@@ -9,7 +9,7 @@ struct TimeTravelBarView : View {
getValue: { Double(self.store.currentStateIndex) }, getValue: { Double(self.store.currentStateIndex) },
setValue: { self.store.currentStateIndex = Int($0) }) setValue: { self.store.currentStateIndex = Int($0) })
return Slider(value: indexBinding, from: 0, through: Double(store.stateCount-1)) return Slider(value: indexBinding, in: 0...Double(store.stateCount-1))
.background(Color.white) .background(Color.white)
.frame(height: 44.0, alignment: .bottom) .frame(height: 44.0, alignment: .bottom)
.padding() .padding()

View File

@@ -11,7 +11,7 @@ struct AddItemView: View {
setValue: { self.store.dispatch(event: .changePartialItemName($0)) }) setValue: { self.store.dispatch(event: .changePartialItemName($0)) })
return VStack(spacing: 16) { return VStack(spacing: 16) {
TextField(textBinding, placeholder: Text("Title")) TextField("Title", text: textBinding)
Button(action: { Button(action: {
self.store.dispatch(event: .addItem) self.store.dispatch(event: .addItem)
}) { }) {
@@ -22,7 +22,7 @@ struct AddItemView: View {
} }
} }
.relativeWidth(1.0) // .relativeWidth(1.0)
.background(Color.accentColor) .background(Color.accentColor)
.disabled(store.state.partialItemName.isEmpty) .disabled(store.state.partialItemName.isEmpty)
.foregroundColor(.white) .foregroundColor(.white)

View File

@@ -7,8 +7,8 @@ struct ModalDimmingView : View {
var body: some View { var body: some View {
Color Color
.black .black
.relativeWidth(1.0) // .relativeWidth(1.0)
.relativeHeight(1.0) // .relativeHeight(1.0)
.opacity(0.3) .opacity(0.3)
.edgesIgnoringSafeArea([.bottom, .top]) .edgesIgnoringSafeArea([.bottom, .top])
.transition(.opacity) .transition(.opacity)

View File

@@ -8,8 +8,8 @@ struct TodoListItemView : View {
var body: some View { var body: some View {
let binding = Binding( let binding = Binding(
getValue: { self.item.isFinished }, get: { self.item.isFinished },
setValue: { self.store.dispatch(event: .setItemDone(identifier: self.item.id, isDone: $0)) }) set: { self.store.dispatch(event: .setItemDone(identifier: self.item.id, isDone: $0)) })
return Toggle(isOn: binding) { return Toggle(isOn: binding) {
Text(item.title) Text(item.title)

View File

@@ -22,7 +22,7 @@ struct TodoListView : View {
VStack { VStack {
Spacer() Spacer()
AddItemView() AddItemView()
.relativeWidth(1.0) // .relativeWidth(1.0)
.background(Color.white) .background(Color.white)
.cornerRadius(12.0) .cornerRadius(12.0)
.shadow(radius: 16.0) .shadow(radius: 16.0)

View File

@@ -19,7 +19,7 @@ struct ContentView: View {
.fontWeight(.semibold) .fontWeight(.semibold)
.foregroundColor(.black) .foregroundColor(.black)
.padding(4) .padding(4)
.animation(.basic(duration: 0.3, curve: .easeOut)) // .animation(.basic(duration: 0.3, curve: .easeOut))
Image("ui") Image("ui")
.frame(width: show ? 414 : 300, height: show ? 600 : 300) .frame(width: show ? 414 : 300, height: show ? 600 : 300)
@@ -35,7 +35,7 @@ struct ContentView: View {
.fontWeight(.regular) .fontWeight(.regular)
.foregroundColor(.gray) .foregroundColor(.gray)
.padding(4) .padding(4)
.animation(.basic(duration: 0.4, curve: .easeIn)) // .animation(.basic(duration: 0.4, curve: .easeIn))
Button(action: { Button(action: {
withAnimation { withAnimation {

View File

@@ -24,8 +24,7 @@ struct NoteDetail : View {
var body: some View { var body: some View {
VStack { VStack {
TextField(self.text.binding, TextField("", text: self.text.binding,
placeholder: nil,
onEditingChanged: { _ in self.updateNote()}, onEditingChanged: { _ in self.updateNote()},
onCommit: {}) onCommit: {})
Spacer() Spacer()

View File

@@ -11,10 +11,11 @@ struct HikeBadge: View {
var name: String var name: String
var body: some View { var body: some View {
VStack(alignment: .center) { VStack(alignment: .center) {
Badge() // crashes in Beta 5
.frame(width: 300, height: 300) // Badge()
.scaleEffect(1.0 / 3.0) // .frame(width: 300, height: 300)
.frame(width: 100, height: 100) // .scaleEffect(1.0 / 3.0)
// .frame(width: 100, height: 100)
Text(name) Text(name)
.font(.caption) .font(.caption)
.accessibility(label: Text("Badge for \(name).")) .accessibility(label: Text("Badge for \(name)."))

View File

@@ -8,6 +8,8 @@ A view showing featured landmarks above a list of all of the landmarks.
import SwiftUI import SwiftUI
struct CategoryHome: View { struct CategoryHome: View {
@State private var isProfilePresented = false
var categories: [String: [Landmark]] { var categories: [String: [Landmark]] {
.init( .init(
grouping: landmarkData, grouping: landmarkData,
@@ -39,12 +41,16 @@ struct CategoryHome: View {
} }
.navigationBarTitle(Text("Featured")) .navigationBarTitle(Text("Featured"))
.navigationBarItems(trailing: .navigationBarItems(trailing:
PresentationLink(destination: ProfileHost()) { Button(action: {
self.isProfilePresented = true
}) {
Image(systemName: "person.crop.circle") Image(systemName: "person.crop.circle")
.imageScale(.large) .imageScale(.large)
.accessibility(label: Text("User Profile")) .accessibility(label: Text("User Profile"))
.padding() .padding()
}) }
).sheet(isPresented: $isProfilePresented,
content: { ProfileHost().environmentObject(UserData()) })
} }
} }
} }

View File

@@ -51,7 +51,7 @@ final class ImageStore {
?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale)
images.values[index][size] = sizedImage images.values[index][size] = sizedImage
return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name))
} }
fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index {

View File

@@ -15,7 +15,7 @@ struct ProfileEditor: View {
HStack { HStack {
Text("Username").bold() Text("Username").bold()
Divider() Divider()
TextField($profile.username) TextField("", text: $profile.username)
} }
Toggle(isOn: $profile.prefersNotifications) { Toggle(isOn: $profile.prefersNotifications) {
@@ -24,21 +24,20 @@ struct ProfileEditor: View {
VStack(alignment: .leading, spacing: 20) { VStack(alignment: .leading, spacing: 20) {
Text("Seasonal Photo").bold() Text("Seasonal Photo").bold()
SegmentedControl(selection: $profile.seasonalPhoto) { Picker("", selection: $profile.seasonalPhoto) {
ForEach(Profile.Season.allCases, id: \.self) { season in ForEach(Profile.Season.allCases, id: \.self) { season in
Text(season.rawValue).tag(season) Text(season.rawValue).tag(season)
} }
} }.pickerStyle(SegmentedPickerStyle())
} }
.padding(.top) .padding(.top)
VStack(alignment: .leading, spacing: 20) { VStack(alignment: .leading, spacing: 20) {
Text("Goal Date").bold() Text("Goal Date").bold()
DatePicker( DatePicker(
$profile.goalDate, "", selection: $profile.goalDate,
minimumDate: Calendar.current.date(byAdding: .year, value: -1, to: profile.goalDate), in: Calendar.current.date(byAdding: .year, value: -1, to: profile.goalDate)! ... Calendar.current.date(byAdding: .year, value: 1, to: profile.goalDate)!,
maximumDate: Calendar.current.date(byAdding: .year, value: 1, to: profile.goalDate),
displayedComponents: .date displayedComponents: .date
) )
} }

View File

@@ -17,7 +17,7 @@ struct ProfileHost: View {
HStack { HStack {
if self.mode?.value == .active { if self.mode?.value == .active {
Button(action: { Button(action: {
self.profile = self.draftProfile self.draftProfile = self.profile
self.mode?.animation().value = .inactive self.mode?.animation().value = .inactive
}) { }) {
Text("Done") Text("Done")
@@ -33,7 +33,7 @@ struct ProfileHost: View {
} else { } else {
ProfileEditor(profile: $draftProfile) ProfileEditor(profile: $draftProfile)
.onDisappear { .onDisappear {
self.draftProfile = self.profile self.profile = self.draftProfile
} }
} }
} }

View File

@@ -9,20 +9,20 @@ import SwiftUI
struct GraphCapsule: View { struct GraphCapsule: View {
var index: Int var index: Int
var height: Length var height: CGFloat
var range: Range<Double> var range: Range<Double>
var overallRange: Range<Double> var overallRange: Range<Double>
var heightRatio: Length { var heightRatio: CGFloat {
max(Length(magnitude(of: range) / magnitude(of: overallRange)), 0.15) max(CGFloat(magnitude(of: range) / magnitude(of: overallRange)), 0.15)
} }
var offsetRatio: Length { var offsetRatio: CGFloat {
Length((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) CGFloat((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange))
} }
var animation: Animation { var animation: Animation {
Animation.spring(initialVelocity: 5) Animation.spring()
.speed(2) .speed(2)
.delay(0.03 * Double(index)) .delay(0.03 * Double(index))
} }

View File

@@ -40,7 +40,7 @@ struct HikeGraph: View {
let data = hike.observations let data = hike.observations
let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] })
let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()!
let heightRatio = 1 - Length(maxMagnitude / magnitude(of: overallRange)) let heightRatio = 1 - CGFloat(maxMagnitude / magnitude(of: overallRange))
return GeometryReader { proxy in return GeometryReader { proxy in
HStack(alignment: .bottom, spacing: proxy.size.width / 120) { HStack(alignment: .bottom, spacing: proxy.size.width / 120) {