WebAppView + viel kaputtes
This commit is contained in:
parent
cd16b94917
commit
42b110637a
13 changed files with 553 additions and 115 deletions
|
|
@ -14,7 +14,7 @@ struct TheSwiftWeek: App {
|
||||||
|
|
||||||
// ContentView()
|
// ContentView()
|
||||||
|
|
||||||
UnicycleView()
|
ContentView()
|
||||||
|
|
||||||
|
|
||||||
}.modelContainer(for: Unicycle.self)
|
}.modelContainer(for: Unicycle.self)
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,21 @@ struct BikeView: TabContent {
|
||||||
static var image = "bicycle"
|
static var image = "bicycle"
|
||||||
|
|
||||||
|
|
||||||
var bike = Bike(name: "Fahrrad", price: 11.31, color: Color.cyan)
|
var bike = Bike(name: "Mein Fahrrad ", price: 11.31, color: Color.cyan)
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack{
|
HStack {
|
||||||
Label(bike.name, systemImage: "bicycle")
|
Label(bike.name, systemImage: "bicycle")
|
||||||
.foregroundStyle(.white)
|
.foregroundStyle(.white)
|
||||||
.padding(5)
|
.padding(5)
|
||||||
.background(bike.color)
|
.background(bike.color)
|
||||||
|
|
||||||
|
// .frame(width: 200)
|
||||||
|
// Spacer()
|
||||||
|
Text(bike.price, format: .currency( code: "EUR"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,45 @@
|
||||||
//
|
|
||||||
// ListView.swift
|
|
||||||
// TheSwiftWeek
|
|
||||||
//
|
|
||||||
// Created by Ingo Rohlf on 21.10.25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
//import Playgrounds
|
struct ListView: TabContent {
|
||||||
import Foundation
|
|
||||||
|
|
||||||
struct ListView: TabContent{
|
|
||||||
static var title = "List"
|
static var title = "List"
|
||||||
static var image = "list.bullet"
|
static var image = "list.bullet"
|
||||||
|
static var id = UUID()
|
||||||
|
|
||||||
@State var bikes = Bike.all
|
@State var bikes = Bike.all
|
||||||
|
@FocusState var focusedField: UUID? // 1
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
List {
|
||||||
Text(bikes[0].name)
|
Section {
|
||||||
Text(bikes[1].name)
|
ForEach($bikes) { $bike in
|
||||||
Text(bikes[2].name)
|
// HStack {
|
||||||
}
|
// TextField("New Bike", text: $bike.name)
|
||||||
List(bikes, id: \.name){ bike in
|
// .focused($focusedField, equals: bike.id)
|
||||||
|
// .textFieldStyle(.roundedBorder)
|
||||||
|
// Spacer()
|
||||||
|
// Text("\(bike.price, specifier: "%.2f€")")
|
||||||
|
// ColorPicker("", selection: $bike.color)
|
||||||
|
// }
|
||||||
HStack {
|
HStack {
|
||||||
|
BikeView(bike: bike)
|
||||||
Color(bike.color)
|
|
||||||
//Circle().fill(style: bike.color)
|
|
||||||
|
|
||||||
|
|
||||||
Text(String(bike.name))
|
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
ColorPicker("", selection: $bike.color)
|
||||||
}
|
|
||||||
List(bikes, id: \.name){
|
|
||||||
Text(String($0.price))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Weil Vehicle jetzt Identifiable implementiert, geht es ohne id: \.name
|
|
||||||
List(bikes){
|
|
||||||
Text(String($0.name))
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.onDelete { bikes.remove(atOffsets: $0) }
|
||||||
|
} footer: {
|
||||||
|
Button("Add a new Bike") {
|
||||||
|
let bike = Bike(name: "", color: .white)
|
||||||
|
bikes.append(bike)
|
||||||
|
// focusedField = bike.id
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .center)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//#Playground {
|
|
||||||
// var students = ["Bill", "Linus"]
|
|
||||||
// let size = [1.65, 1.79]
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
ListView()
|
ListView()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
{
|
{
|
||||||
"sourceLanguage" : "en",
|
"sourceLanguage" : "en",
|
||||||
"strings" : {
|
"strings" : {
|
||||||
|
"" : {
|
||||||
|
|
||||||
|
},
|
||||||
"%lld" : {
|
"%lld" : {
|
||||||
"comment" : "A text element displaying a number. The content of the text element is the integer passed to this view's initializer.",
|
"comment" : "A text element displaying a number. The content of the text element is the integer passed to this view's initializer.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
},
|
},
|
||||||
"Add Bike" : {
|
"Add a new Bike" : {
|
||||||
"comment" : "A button that adds a new bike to the list of bikes.",
|
"comment" : "A button that allows adding a new bike to the list.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
},
|
},
|
||||||
"Add unicycle" : {
|
"Add Bike" : {
|
||||||
"comment" : "A button that adds a new unicycle to the list.",
|
"comment" : "A button that adds a new bike to the list of bikes.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
},
|
},
|
||||||
"Bikes" : {
|
"Bikes" : {
|
||||||
|
|
@ -33,10 +36,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Einrad von %@" : {
|
|
||||||
"comment" : "A list item displaying the creation date of a unicycle.",
|
|
||||||
"isCommentAutoGenerated" : true
|
|
||||||
},
|
|
||||||
"Enter Emoji" : {
|
"Enter Emoji" : {
|
||||||
"comment" : "A label for an text field where the user can enter an emoji.",
|
"comment" : "A label for an text field where the user can enter an emoji.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
|
|
@ -45,10 +44,6 @@
|
||||||
"comment" : "A word that is displayed when the number is a multiple of 3.",
|
"comment" : "A word that is displayed when the number is a multiple of 3.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
},
|
},
|
||||||
"Hello, World!" : {
|
|
||||||
"comment" : "A greeting message displayed in the preview.",
|
|
||||||
"isCommentAutoGenerated" : true
|
|
||||||
},
|
|
||||||
"My Vehicle" : {
|
"My Vehicle" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
|
|
@ -66,6 +61,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"please update to iOS 26.0 or later" : {
|
||||||
|
"comment" : "A message to inform the user that they need to update their iOS version to 26.0 or later to use this feature.",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
|
},
|
||||||
"Show Alert" : {
|
"Show Alert" : {
|
||||||
"comment" : "A button that triggers an alert when pressed.",
|
"comment" : "A button that triggers an alert when pressed.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
|
|
@ -124,6 +123,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"WebView für iOS 26+" : {
|
||||||
|
"comment" : "A title for the view that displays a web view.",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version" : "1.1"
|
"version" : "1.1"
|
||||||
|
|
|
||||||
20
Models.swift
20
Models.swift
|
|
@ -48,11 +48,23 @@ struct Train: @MainActor Vehicle, CustomStringConvertible , CustomLocalizedStrin
|
||||||
self.content = content()
|
self.content = content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
enum BikeType: String, Codable, CaseIterable, Identifiable {
|
||||||
|
var id: String { rawValue }
|
||||||
|
|
||||||
|
case unknown
|
||||||
|
case mountain
|
||||||
|
case city
|
||||||
|
case gravel
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Bike: @MainActor Vehicle, CustomStringConvertible {
|
struct Bike: @MainActor Vehicle, CustomStringConvertible {
|
||||||
var name: String
|
var name: String
|
||||||
var price: Double
|
var price: Double = Double(Int.random(in: 3...8)*50) - 0.51
|
||||||
var color: Color
|
var color: Color
|
||||||
|
var type: BikeType = .unknown
|
||||||
|
|
||||||
|
|
||||||
// var description: String { name + " is " + color }
|
// var description: String { name + " is " + color }
|
||||||
var description: String {"\(name) is \(color)" }
|
var description: String {"\(name) is \(color)" }
|
||||||
|
|
||||||
|
|
@ -63,8 +75,8 @@ struct Bike: @MainActor Vehicle, CustomStringConvertible {
|
||||||
print("emptied", Date())
|
print("emptied", Date())
|
||||||
}
|
}
|
||||||
static var all: [Bike] = [
|
static var all: [Bike] = [
|
||||||
Bike(name: "Specialized",price: 100000.00, color: .purple ),
|
Bike(name: "Specialized",price: 149.98, color: .purple ),
|
||||||
Bike(name: "Giant",price: 120000.00, color: .red ),
|
Bike(name: "Giant",price: 129.00, color: .red ),
|
||||||
Bike(name: "Cannondale",price: 110000.00, color: .green )
|
Bike(name: "Cannondale",price: 299.00, color: .green )
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
100
NewUnicycleView.swift
Normal file
100
NewUnicycleView.swift
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//import SwiftUI
|
||||||
|
//import SwiftData
|
||||||
|
//
|
||||||
|
//struct NewUnicycleView: View {
|
||||||
|
// @Environment(\.modelContext) private var modelContext
|
||||||
|
//
|
||||||
|
// @State private var isPresented = false
|
||||||
|
// @State private var sortOrder = SortDescriptor(\Unicycle.name)
|
||||||
|
// @State private var search = ""
|
||||||
|
//
|
||||||
|
// var body: some View {
|
||||||
|
// NavigationStack {
|
||||||
|
// UniListView(filter: search, sort: sortOrder)
|
||||||
|
// .searchable(text: $search)
|
||||||
|
// .toolbar {
|
||||||
|
// ToolbarItem(placement: .topBarLeading) {
|
||||||
|
// EditButton()
|
||||||
|
// }
|
||||||
|
// ToolbarItem(placement: .topBarTrailing) {
|
||||||
|
// HStack {
|
||||||
|
//
|
||||||
|
// Button("Add", systemImage: "plus") { isPresented = true }
|
||||||
|
// picker
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .sheet(isPresented: $isPresented) {
|
||||||
|
// UniDetailView(uni: Unicycle())
|
||||||
|
// }
|
||||||
|
// Button("Save 3") {
|
||||||
|
// try? modelContext.save()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var picker: some View {
|
||||||
|
// Menu("Sort", systemImage: "arrow.up.arrow.down") {
|
||||||
|
// Picker("Sort", selection: $sortOrder) {
|
||||||
|
// Text("Name 55")
|
||||||
|
// .tag(SortDescriptor(\Unicycle.name))
|
||||||
|
// Text("Date")
|
||||||
|
// .tag(SortDescriptor(\Unicycle.createdAt, order: .reverse))
|
||||||
|
// Button("Save") {
|
||||||
|
// try? modelContext.save()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// .pickerStyle(.inline)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// struct UniDetailView: View {
|
||||||
|
// @Bindable var uni: Unicycle
|
||||||
|
// @State var color: Color
|
||||||
|
// @Environment(\.modelContext) private var modelContext
|
||||||
|
//
|
||||||
|
// init(uni: Unicycle) {
|
||||||
|
// self.uni = uni
|
||||||
|
// _color = State(initialValue: Color(red: uni.red, green: uni.green, blue: uni.blue))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var body: some View {
|
||||||
|
// VStack {
|
||||||
|
// Text(uni.createdAt.description)
|
||||||
|
// ColorPicker("Color", selection: Binding(
|
||||||
|
// get: { color as! CGColor },
|
||||||
|
// set: {
|
||||||
|
// color = $0
|
||||||
|
//// if let comps = $0.rgbComponents() {
|
||||||
|
//// uni.red = Double(comps.red)
|
||||||
|
//// uni.green = Double(comps.green)
|
||||||
|
//// uni.blue = Double(comps.blue)
|
||||||
|
//// }
|
||||||
|
// }
|
||||||
|
// ))
|
||||||
|
// TextField("Enter name", text: $uni.name)
|
||||||
|
// .textFieldStyle(.roundedBorder)
|
||||||
|
// .padding()
|
||||||
|
// Button("Save 3") {
|
||||||
|
// try? modelContext.save()
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .padding()
|
||||||
|
// .onChange(of: color) {
|
||||||
|
// if let comps = color.rgbComponents() {
|
||||||
|
// uni.red = Double(comps.red)
|
||||||
|
// uni.green = Double(comps.green)
|
||||||
|
// uni.blue = Double(comps.blue)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//#Preview {
|
||||||
|
// NewUnicycleView()
|
||||||
|
//}
|
||||||
|
|
@ -25,6 +25,9 @@
|
||||||
FBA6FA622EA76AAD00C373EC /* BikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBA6FA612EA76AAD00C373EC /* BikeView.swift */; };
|
FBA6FA622EA76AAD00C373EC /* BikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBA6FA612EA76AAD00C373EC /* BikeView.swift */; };
|
||||||
FBA6FA642EA7715E00C373EC /* Extentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBA6FA632EA7715000C373EC /* Extentions.swift */; };
|
FBA6FA642EA7715E00C373EC /* Extentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBA6FA632EA7715000C373EC /* Extentions.swift */; };
|
||||||
FBA6FA662EA7725A00C373EC /* TrainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBA6FA652EA7725A00C373EC /* TrainView.swift */; };
|
FBA6FA662EA7725A00C373EC /* TrainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBA6FA652EA7725A00C373EC /* TrainView.swift */; };
|
||||||
|
FBE1A29D2EAA1B4300081638 /* UniView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBE1A29C2EAA1B4300081638 /* UniView.swift */; };
|
||||||
|
FBE1A29F2EAA225600081638 /* NewUnicycleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBE1A29E2EAA225600081638 /* NewUnicycleView.swift */; };
|
||||||
|
FBE1A2A12EAA340F00081638 /* WebAppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBE1A2A02EAA340F00081638 /* WebAppView.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
|
@ -47,6 +50,9 @@
|
||||||
FBA6FA612EA76AAD00C373EC /* BikeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BikeView.swift; sourceTree = "<group>"; };
|
FBA6FA612EA76AAD00C373EC /* BikeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BikeView.swift; sourceTree = "<group>"; };
|
||||||
FBA6FA632EA7715000C373EC /* Extentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extentions.swift; sourceTree = "<group>"; };
|
FBA6FA632EA7715000C373EC /* Extentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extentions.swift; sourceTree = "<group>"; };
|
||||||
FBA6FA652EA7725A00C373EC /* TrainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrainView.swift; sourceTree = "<group>"; };
|
FBA6FA652EA7725A00C373EC /* TrainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrainView.swift; sourceTree = "<group>"; };
|
||||||
|
FBE1A29C2EAA1B4300081638 /* UniView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UniView.swift; sourceTree = "<group>"; };
|
||||||
|
FBE1A29E2EAA225600081638 /* NewUnicycleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewUnicycleView.swift; sourceTree = "<group>"; };
|
||||||
|
FBE1A2A02EAA340F00081638 /* WebAppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebAppView.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
|
@ -63,6 +69,7 @@
|
||||||
0CC14A6D2E92EC4700271E8D = {
|
0CC14A6D2E92EC4700271E8D = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
FBE1A2A02EAA340F00081638 /* WebAppView.swift */,
|
||||||
FBA00D742EA7ACDD006F8B9A /* SwapperView.swift */,
|
FBA00D742EA7ACDD006F8B9A /* SwapperView.swift */,
|
||||||
FBA00D702EA7A830006F8B9A /* PaddingView.swift */,
|
FBA00D702EA7A830006F8B9A /* PaddingView.swift */,
|
||||||
FBA00D6E2EA78850006F8B9A /* Color.swift */,
|
FBA00D6E2EA78850006F8B9A /* Color.swift */,
|
||||||
|
|
@ -75,6 +82,8 @@
|
||||||
FBA6FA612EA76AAD00C373EC /* BikeView.swift */,
|
FBA6FA612EA76AAD00C373EC /* BikeView.swift */,
|
||||||
FB79FE472EA8F74F0011678F /* BikeSwipeView.swift */,
|
FB79FE472EA8F74F0011678F /* BikeSwipeView.swift */,
|
||||||
FB79FE492EA906CC0011678F /* UnicycleView.swift */,
|
FB79FE492EA906CC0011678F /* UnicycleView.swift */,
|
||||||
|
FBE1A29E2EAA225600081638 /* NewUnicycleView.swift */,
|
||||||
|
FBE1A29C2EAA1B4300081638 /* UniView.swift */,
|
||||||
FB79FE4B2EA9071F0011678F /* Unicycle.swift */,
|
FB79FE4B2EA9071F0011678F /* Unicycle.swift */,
|
||||||
FBA6FA652EA7725A00C373EC /* TrainView.swift */,
|
FBA6FA652EA7725A00C373EC /* TrainView.swift */,
|
||||||
FB2F07E82EA7CB25002BD499 /* ListView.swift */,
|
FB2F07E82EA7CB25002BD499 /* ListView.swift */,
|
||||||
|
|
@ -168,6 +177,7 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
FBE1A29D2EAA1B4300081638 /* UniView.swift in Sources */,
|
||||||
FBA6FA5E2EA63EA300C373EC /* Models.swift in Sources */,
|
FBA6FA5E2EA63EA300C373EC /* Models.swift in Sources */,
|
||||||
FB79FE482EA8F74F0011678F /* BikeSwipeView.swift in Sources */,
|
FB79FE482EA8F74F0011678F /* BikeSwipeView.swift in Sources */,
|
||||||
FB79FE462EA8CFD20011678F /* RangeView.swift in Sources */,
|
FB79FE462EA8CFD20011678F /* RangeView.swift in Sources */,
|
||||||
|
|
@ -178,7 +188,9 @@
|
||||||
FBA6FA642EA7715E00C373EC /* Extentions.swift in Sources */,
|
FBA6FA642EA7715E00C373EC /* Extentions.swift in Sources */,
|
||||||
FB79FE4A2EA906CC0011678F /* UnicycleView.swift in Sources */,
|
FB79FE4A2EA906CC0011678F /* UnicycleView.swift in Sources */,
|
||||||
0CC14A872E92EC7B00271E8D /* App.swift in Sources */,
|
0CC14A872E92EC7B00271E8D /* App.swift in Sources */,
|
||||||
|
FBE1A29F2EAA225600081638 /* NewUnicycleView.swift in Sources */,
|
||||||
FBA00D732EA7A96C006F8B9A /* ContentView.swift in Sources */,
|
FBA00D732EA7A96C006F8B9A /* ContentView.swift in Sources */,
|
||||||
|
FBE1A2A12EAA340F00081638 /* WebAppView.swift in Sources */,
|
||||||
FBA00D6F2EA78853006F8B9A /* Color.swift in Sources */,
|
FBA00D6F2EA78853006F8B9A /* Color.swift in Sources */,
|
||||||
FB2F07E92EA7CB25002BD499 /* ListView.swift in Sources */,
|
FB2F07E92EA7CB25002BD499 /* ListView.swift in Sources */,
|
||||||
FBA00D712EA7A839006F8B9A /* PaddingView.swift in Sources */,
|
FBA00D712EA7A839006F8B9A /* PaddingView.swift in Sources */,
|
||||||
|
|
@ -327,6 +339,7 @@
|
||||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 18.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|
@ -358,6 +371,7 @@
|
||||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 18.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -3,22 +3,4 @@
|
||||||
uuid = "543AEB13-B7EA-4C8C-9F73-C23287B3971E"
|
uuid = "543AEB13-B7EA-4C8C-9F73-C23287B3971E"
|
||||||
type = "1"
|
type = "1"
|
||||||
version = "2.0">
|
version = "2.0">
|
||||||
<Breakpoints>
|
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "B8EA1D18-A70B-45BA-91B0-542F11641B66"
|
|
||||||
shouldBeEnabled = "Yes"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "BikeView.swift"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "1"
|
|
||||||
endingLineNumber = "1"
|
|
||||||
landmarkName = "unknown"
|
|
||||||
landmarkType = "0">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
</Breakpoints>
|
|
||||||
</Bucket>
|
</Bucket>
|
||||||
|
|
|
||||||
132
UniView.swift
Normal file
132
UniView.swift
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
//import SwiftUI
|
||||||
|
//import SwiftData
|
||||||
|
//
|
||||||
|
////@Model class Unicycle {
|
||||||
|
//// var createdAt = Date()
|
||||||
|
//// var name = ""
|
||||||
|
//// var red = 1.0
|
||||||
|
//// var green = 1.0
|
||||||
|
//// var blue = 1.0
|
||||||
|
//// init() { } // You can't escape this
|
||||||
|
////}
|
||||||
|
//
|
||||||
|
//struct UniView: View {
|
||||||
|
// @Environment(\.modelContext) private var modelContext
|
||||||
|
// @Query private var unis: [Unicycle]
|
||||||
|
// @State private var selection = Set<PersistentIdentifier>()
|
||||||
|
// @Environment(\.editMode) private var editMode
|
||||||
|
// @State private var edit: EditMode = .inactive
|
||||||
|
//
|
||||||
|
// var body: some View {
|
||||||
|
// NavigationStack {
|
||||||
|
// List(selection: $selection) {
|
||||||
|
// ForEach(unis) { uni in
|
||||||
|
// NavigationLink(uni.createdAt.description) {
|
||||||
|
// UniDetailView(uni: uni)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .onDelete { indexSet in
|
||||||
|
// for index in indexSet {
|
||||||
|
// modelContext.delete(unis[index])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .toolbar {
|
||||||
|
//// ToolbarItem(placement: .topBarLeading) {
|
||||||
|
// if !unis.isEmpty { EditButton() }
|
||||||
|
//// }
|
||||||
|
//// ToolbarItem(placement: .topBarTrailing) {
|
||||||
|
// if edit == .active {
|
||||||
|
// if !selectedUnis.isEmpty {
|
||||||
|
// Button("Delete \(selectedUnis.count)", role: .destructive) {
|
||||||
|
// // Map selection to models and delete
|
||||||
|
// for uni in selectedUnis {
|
||||||
|
// modelContext.delete(uni)
|
||||||
|
// }
|
||||||
|
// selection.removeAll()
|
||||||
|
// }
|
||||||
|
// .disabled(selection.isEmpty)
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// Button("Add") {
|
||||||
|
// modelContext.insert(Unicycle())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//// }
|
||||||
|
// }
|
||||||
|
// .environment(\.editMode, $edit) // <-- Provide the binding
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @MainActor
|
||||||
|
// var selectedUnis: [Unicycle] {
|
||||||
|
// unis.filter { selection.contains($0.id) }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//struct UniDetailView: View {
|
||||||
|
// @Bindable var uni: Unicycle
|
||||||
|
// @State var color: Color
|
||||||
|
// @Environment(\.modelContext) private var modelContext
|
||||||
|
//
|
||||||
|
// init(uni: Unicycle) {
|
||||||
|
// self.uni = uni
|
||||||
|
// _color = State(initialValue: Color(red: uni.red, green: uni.green, blue: uni.blue))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var body: some View {
|
||||||
|
// VStack {
|
||||||
|
// Text(uni.createdAt.description)
|
||||||
|
// ColorPicker("Color", selection: Binding(
|
||||||
|
// get: { color },
|
||||||
|
// set: {
|
||||||
|
// color = $0
|
||||||
|
// if let comps = $0.rgbComponents() {
|
||||||
|
// uni.red = Double(comps.red)
|
||||||
|
// uni.green = Double(comps.green)
|
||||||
|
// uni.blue = Double(comps.blue)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ))
|
||||||
|
// TextField("Enter name", text: $uni.name)
|
||||||
|
// .textFieldStyle(.roundedBorder)
|
||||||
|
// .padding()
|
||||||
|
// Button("Save 3") {
|
||||||
|
// try? modelContext.save()
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .padding()
|
||||||
|
// .onChange(of: color) {
|
||||||
|
// if let comps = color.rgbComponents() {
|
||||||
|
// uni.red = Double(comps.red)
|
||||||
|
// uni.green = Double(comps.green)
|
||||||
|
// uni.blue = Double(comps.blue)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//extension Color {
|
||||||
|
// func rgbComponents() -> (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)? {
|
||||||
|
// // Convert SwiftUI Color to UIColor
|
||||||
|
// let uiColor = UIColor(self)
|
||||||
|
//
|
||||||
|
// var r: CGFloat = 0
|
||||||
|
// var g: CGFloat = 0
|
||||||
|
// var b: CGFloat = 0
|
||||||
|
// var a: CGFloat = 0
|
||||||
|
//
|
||||||
|
// guard uiColor.getRed(&r, green: &g, blue: &b, alpha: &a) else {
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
// return (r, g, b, a)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//#Preview {
|
||||||
|
// UniView()
|
||||||
|
// .modelContainer(for: Unicycle.self)
|
||||||
|
//}
|
||||||
|
|
@ -1,13 +1,37 @@
|
||||||
import SwiftData
|
import SwiftData
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@Model class Unicycle {
|
||||||
|
var createdAt: Date
|
||||||
|
var name: String
|
||||||
|
var red: CGFloat
|
||||||
|
var green: CGFloat
|
||||||
|
var blue: CGFloat
|
||||||
|
var alpha: CGFloat
|
||||||
|
|
||||||
@Model class Unicycle{
|
// Default values for all properties
|
||||||
var createdAt: Date = Date()
|
init(createdAt: Date = Date(), name: String = "", red: CGFloat = CGFloat.random(in: 0...1), green: CGFloat = CGFloat.random(in: 0...1), blue: CGFloat = CGFloat.random(in: 0...1), alpha: CGFloat = 1) {
|
||||||
init(createdAt: Date) {
|
|
||||||
self.createdAt = createdAt
|
self.createdAt = createdAt
|
||||||
|
self.name = name
|
||||||
|
self.red = red
|
||||||
|
self.green = green
|
||||||
|
self.blue = blue
|
||||||
|
self.alpha = alpha
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var color: Color {
|
||||||
|
get { Color(red: red, green: green, blue: blue,
|
||||||
|
opacity: alpha) }
|
||||||
|
set {
|
||||||
|
UIColor(newValue).getRed(
|
||||||
|
&red,
|
||||||
|
green: &green,
|
||||||
|
blue: &blue,
|
||||||
|
alpha: &alpha
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,158 @@
|
||||||
import SwiftData
|
//import SwiftData
|
||||||
import SwiftUI
|
//import SwiftUI
|
||||||
|
//
|
||||||
struct UnicycleView2: View {
|
//struct UnicycleView2: View {
|
||||||
var body: some View {
|
// var body: some View {
|
||||||
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
// Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
struct UnicycleView: View {
|
//struct UnicycleView: View {
|
||||||
@Environment(\.modelContext) private var modelContext
|
// @Environment(\.modelContext) private var modelContext
|
||||||
@Query private var unis: [Unicycle]
|
// @Query private var unis: [Unicycle]
|
||||||
|
//
|
||||||
var body: some View {
|
// var body: some View {
|
||||||
Button("Add unicycle") {
|
// Button("Add unicycle") {
|
||||||
modelContext.insert(Unicycle(createdAt: Date()))
|
// modelContext.insert(Unicycle(createdAt: Date()))
|
||||||
}
|
// }
|
||||||
List{
|
// List{
|
||||||
ForEach(unis) { uni in
|
// ForEach(unis) { uni in
|
||||||
Text("Einrad von \(uni.createdAt.description)")
|
// Text("Einrad von \(uni.createdAt.description)")
|
||||||
}.onDelete {
|
// }.onDelete {
|
||||||
for index in $0 {
|
// for index in $0 {
|
||||||
modelContext.delete(unis[index])
|
// modelContext.delete(unis[index])
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
#Preview {
|
//
|
||||||
UnicycleView2()
|
//
|
||||||
}
|
//
|
||||||
|
//struct UniListView: View {
|
||||||
|
// @Environment(\.modelContext) private var modelContext
|
||||||
|
// @Query private var unis: [Unicycle]
|
||||||
|
//
|
||||||
|
// init(filter: String, sort: SortDescriptor<Unicycle>) {
|
||||||
|
// _unis = Query(filter: #Predicate<Unicycle> {
|
||||||
|
// filter.isEmpty || $0.name.contains(filter)
|
||||||
|
// }, sort: [sort])
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var body: some View {
|
||||||
|
// List {
|
||||||
|
// ForEach(unis) { u in
|
||||||
|
// NavigationLink {
|
||||||
|
// UniDetailView(uni: u)
|
||||||
|
// } label: {
|
||||||
|
// HStack {
|
||||||
|
// VStack(alignment: .leading) {
|
||||||
|
// Text(u.name)
|
||||||
|
// Text(u.createdAt.description)
|
||||||
|
// .font(.caption)
|
||||||
|
// }
|
||||||
|
// Spacer()
|
||||||
|
// ColorPicker("", selection: .constant(u.color))
|
||||||
|
// .disabled(true)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .onDelete {
|
||||||
|
// for index in $0 { // [2, 3]
|
||||||
|
// modelContext.delete(unis[index])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .navigationTitle("\(unis.count) Unicycles")
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//struct UnicycleView3: View {
|
||||||
|
// @Environment(\.modelContext) private var modelContext
|
||||||
|
//
|
||||||
|
// @State private var isPresented = false
|
||||||
|
// @State private var sortOrder = SortDescriptor(\Unicycle.name)
|
||||||
|
// @State private var search = ""
|
||||||
|
//
|
||||||
|
// var body: some View {
|
||||||
|
// NavigationStack {
|
||||||
|
// UniListView(filter: search, sort: sortOrder)
|
||||||
|
// .searchable(text: $search)
|
||||||
|
// .toolbar {
|
||||||
|
// ToolbarItem(placement: .topBarLeading) {
|
||||||
|
// EditButton()
|
||||||
|
// }
|
||||||
|
// ToolbarItem(placement: .topBarTrailing) {
|
||||||
|
// HStack {
|
||||||
|
// Button("Add", systemImage: "plus") { isPresented = true }
|
||||||
|
// picker
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .sheet(isPresented: $isPresented) {
|
||||||
|
// UniDetailView(uni: Unicycle())
|
||||||
|
// }
|
||||||
|
// Button("Save") {
|
||||||
|
// try? modelContext.save()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var picker: some View {
|
||||||
|
// Menu("Sort", systemImage: "arrow.up.arrow.down") {
|
||||||
|
// Picker("Sort", selection: $sortOrder) {
|
||||||
|
// Text("Name")
|
||||||
|
// .tag(SortDescriptor(\Unicycle.name))
|
||||||
|
// Text("Date")
|
||||||
|
// .tag(SortDescriptor(\Unicycle.createdAt, order: .reverse))
|
||||||
|
// }
|
||||||
|
// .pickerStyle(.inline)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//struct UniDetailView2: View {
|
||||||
|
// @Environment(\.modelContext) private var modelContext
|
||||||
|
// @Bindable var uni: Unicycle
|
||||||
|
// @Environment(\.dismiss) private var dismiss
|
||||||
|
//
|
||||||
|
// var body: some View {
|
||||||
|
// Form {
|
||||||
|
// DefaultTextField("Enter a name", $uni.name)
|
||||||
|
// ColorPicker("Color", selection: $uni.color)
|
||||||
|
// Button("Save") {
|
||||||
|
// modelContext.insert(uni)
|
||||||
|
// dismiss()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//struct DefaultTextField: View {
|
||||||
|
// @FocusState private var isFocused: Bool
|
||||||
|
// private var placeholder: String
|
||||||
|
// private var text: Binding<String>
|
||||||
|
//
|
||||||
|
// init(_ placeholder: String = "", _ text: Binding<String>) {
|
||||||
|
// self.placeholder = placeholder
|
||||||
|
// self.text = text
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var body: some View {
|
||||||
|
// TextField(placeholder, text: text)
|
||||||
|
// .focused($isFocused)
|
||||||
|
// .onAppear { isFocused = true }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//#Preview {
|
||||||
|
// UnicycleView()
|
||||||
|
// .modelContainer(for: Unicycle.self)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//#Preview {
|
||||||
|
// UnicycleView()
|
||||||
|
//}
|
||||||
|
|
|
||||||
51
WebAppView.swift
Normal file
51
WebAppView.swift
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// WebView.swift
|
||||||
|
// TheSwiftWeek
|
||||||
|
//
|
||||||
|
// Created by Ingo Rohlf on 23.10.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
import WebKit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct WebAppView: View {
|
||||||
|
// @State private var page = WebPage()
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
|
||||||
|
if let url = URL(string: "https://git.irohlf.de") {
|
||||||
|
|
||||||
|
if #available(iOS 27.0, *) {
|
||||||
|
Text("WebView für iOS 26+")
|
||||||
|
WebView(url: url)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Text("please update to iOS 26.0 or later")
|
||||||
|
WebOldView(url: URL(string: "https://ai.irohlf.de")!)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WebOldView: UIViewRepresentable {
|
||||||
|
let url: URL
|
||||||
|
typealias UIViewType = WKWebView
|
||||||
|
func makeUIView(context: Context) -> WKWebView {
|
||||||
|
.init()
|
||||||
|
}
|
||||||
|
func updateUIView(_ uiView: WKWebView, context: Context) {
|
||||||
|
uiView.load(URLRequest(url: url))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
WebAppView()
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue