Mit einer einfachen Zeile Code einfach mal eine Anzahl Minuten zu dem aktuellen Datum hinzufügen.
let futureDate = Calendar.current.date(byAdding: .minute, value: 10080, to: Date())
Mit einer einfachen Zeile Code einfach mal eine Anzahl Minuten zu dem aktuellen Datum hinzufügen.
let futureDate = Calendar.current.date(byAdding: .minute, value: 10080, to: Date())
So einfach lässt sich ein 2D Array durchlaufen.
for obj in self.oListDatasource.ListOfListEntries { print("rowID: \(String(obj.rowID))") }
Dieser Beitrag erklärt, wie man eine App mit entsprechender Aktion über einen Link öffnen kann. In diesem Beispiel könnte mann die App mit dem Link geileapp://wert öffnen.
Passe dafür zuerst Deine Info.plist an. Rechte Maustaste und dann als Sourcecode bearbeiten. Füge den Code für die Einträge einfach ein.
CFBundleURLTypes CFBundleURLName CFBundleURLSchemes geileapp
Nun brauchst Du noch diesen Code-Block in der SceneDelegate.swift. Das Ereignis wird ausgelöst, wenn jemand Die App über den Link hostet. Das was an Stelle von Wert im Link enthalten ist, findest Du dann in der Variablen context.url.host wieder und kannst entsprechend agieren. In diesem Beispiel wird die View NewView() geöffnet. Zum testen kannst Du einfach ein Standard-Projekt erstellen und auch gerne die ContentView() öffnen.
func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { for context in URLContexts { print("url: \(context.url.absoluteURL)") print("scheme: \(context.url.scheme)") print("host: \(context.url.host)") print("path: \(context.url.path)") print("components: \(context.url.pathComponents)") } let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext let contentView = NewView().environment(\.managedObjectContext, context) if let windowScene = scene as? UIWindowScene { let window = UIWindow(windowScene: windowScene) window.rootViewController = UIHostingController(rootView: contentView) self.window = window window.makeKeyAndVisible() } // NewView().sStest = "x" }
Eine ganze Reihe von Ansichten sind noch nicht in SwiftUI vertreten, aber es ist einfach, sie in das System zu portieren. Sie müssen UIActivityIndicator umbrechen und UIViewRepresentable machen.
import SwiftUI struct ContentView: View { @State var isShowing = false var body: some View { LoadingView(isShowing: $isShowing) { NavigationView { List(["1", "2", "3", "4", "5"], id: \.self) { row in Text(row) }.navigationBarTitle(Text("A List"), displayMode: .large) .navigationBarItems(leading: VStack{ Button(action: { self.Show() }) { Text("Show") } } ) .onAppear() { self.isShowing = true //doing things self.isShowing = false } } } } func Show() { isShowing = true; } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct ActivityIndicator: UIViewRepresentable { @Binding var isAnimating: Bool let style: UIActivityIndicatorView.Style func makeUIView(context: UIViewRepresentableContext) -> UIActivityIndicatorView { return UIActivityIndicatorView(style: style) } func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext ) { isAnimating ? uiView.startAnimating() : uiView.stopAnimating() } } struct LoadingView : View where Content: View { @Binding var isShowing: Bool var content: () -> Content var body: some View { GeometryReader { geometry in ZStack(alignment: .center) { self.content() .disabled(self.isShowing) .blur(radius: self.isShowing ? 3 : 0) VStack { Text("Loading...") ActivityIndicator(isAnimating: .constant(true), style: .large) } .frame(width: geometry.size.width / 2, height: geometry.size.height / 5) .background(Color.secondary.colorInvert()) .foregroundColor(Color.primary) .cornerRadius(20) .opacity(self.isShowing ? 1 : 0) } } } }
Hier ein Beispiel für das Speichern eines Arrays in den User defaults. In dem Array sind Wertpaare gespeichert. Die User defaults eignen sich für kleine Datenmengen und dazu zählt meiner Meinung auch ein kleines Array. Das ist eine schöne Methode um ein paar Daten abzulegen. In diesem Beispiel sind es 3 Datensätze, die abgelegt werden.
func ArrayTest() -> Int { let defaults = UserDefaults.standard let dict = ["Name": "Puppa","Strasse": "Meilershausener Str. 3","Ort": "00099 Testen"] defaults.set(dict, forKey: "myArray") let mySavedArray = defaults.object(forKey: "myArray") as? [String: String] ?? [String: String]() for s in mySavedArray { print(s) } return mySavedArray.count }
So sieht die Ausgabe aus:
(key: "Ort", value: "00099 Testen") (key: "Strasse", value: "Meilershausener Str. 3") (key: "Name", value: "Puppa")
Und natürlich noch ein Beispiel für ein eindimensionales Array:
func ArrayTest1dimensional() -> Int { let defaults = UserDefaults.standard let TheArray = ["a","b","c","d","e"] defaults.set(TheArray, forKey: "myArray2") let mySavedArray = defaults.object(forKey: "myArray2") as? [String] ?? [String]() for s in mySavedArray { print(s) } return mySavedArray.count }
Ja, unter Swift UI ist alles ein bisschen anders – aber cool! Bei meinen ersten Versuchen haben absolute Kleinigkeiten eine halbe Ewigkeit gedauert. So auch hier. Ein einfach Wunsch! Einfach mal einen Event für Enter abgreifen. Damit Ihre nicht so lange suchen müsst, hier ein einfaches Beispiel wie man mit einem Return in einem TextField reagieren kann. Schliesslich drückt der iPhone bzw. IOS App Nutzer gerne auf Öffnen, anstatt einen Button zu klicken. Also geht kein Weg am Abgreifen eines Returns vorbei. Leg Dir einfach ein Testprojekt an und gib Dir die Zeit um um mit dem Beispiel zu spielen. Der Trick liegt hier im onCommit bzw. für den veränderten Wert des Textfelds onEditingChanged. Hier darfst Du dann eine andere Funktion aufrufen, um Dinge auszuführen.
import SwiftUI struct ContentView: View { @State var output: String = "" @State var input: String = "" @State var typing = false var body: some View { VStack { if !typing { if !output.isEmpty { Text("You typed: \(output)") } } else if !input.isEmpty { Text("You are typing: \(input)") } TextField("", text: $input, onEditingChanged: { self.typing = $0 }, onCommit: { self.output = self.input }) .background(Color.green.opacity(0.2)) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Der Toggle Switch in SwiftUI hat leider keinen „action“ event, wie der Button. Wenn man in die geschweiften Klammern einen Funktionsaufruf einträgt, für das zu folgender Fehlermeldung:
Static method ‚buildBlock‘ requires that ‚String‘ conform to ‚View‘
Der Trick ist, dass man hier ein View erzeugen muss.
Im Beispielcode findest Du die Zeile:
Text("Toggle \(ToggleAction(State: showResubmission))")
// // ContentView.swift // ToggleSwitchActionDemo // // Created by T. Stephan on 22.02.20. // Copyright © 2020 eCommerce - Tobias Stephan. All rights reserved. // import SwiftUI import Combine class MainClass: ObservableObject { public var ToggleSwitchState = false init(){ } } struct ContentView: View { @ObservedObject var oMainClass = MainClass() @State private var showResubmission = false var body: some View { Toggle(isOn: $showResubmission){ Text("Toggle \(ToggleAction(State: showResubmission))") .padding() } } func ToggleAction(State: Bool) -> String { if (State != oMainClass.ToggleSwitchState) { oMainClass.ToggleSwitchState = State //do something else... print("Toggle switched...") } return String(State) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Wenn Du Deine Breakpoints entfernen möchtest, findest Du links oben das Breakpoint Symbol hier erhältst Du einen guten Überblick über alle gesetzten Breakpoints. Diese können einzeln oder alle auf einmal entfernt werden.
Die Datumsstruktur von Swift entspricht sowohl der Gleichheit als auch der Vergleichbarkeit, d.h. Du überprüfst zwei Daten auf Gleichheit und vergleichen sie, um zu sehen, welches früher ist, also in der Vergangenheit liegt.
In der Praxis bedeutet dies, dass Du <, > und == verwendest, um zu vergleichen. Genau so, wie Du es mit Zeichenketten und ganzen Zahlen umgingest. Probier es einfach mal aus:
let now = Date() let soon = Date().addingTimeInterval(5000) now == soon now != soon now < soon now > soon
Wenn Du eine SwiftUI-Ansicht mit Hilfe eines Blattes anzeigst, ist es üblich, dass Du diese View schliessen möchtest , wenn etwas passiert – wenn der Benutzer z.B. auf eine Schaltfläche tippt. Es gibt zwei Möglichkeiten, dies in Swift zu lösen, und ich werde Dir beide zeigen, damit Du entscheiden kannst, welche Deinen Bedürfnissen entspricht.
Die erste Möglichkeit besteht darin, der Ansicht zu sagen, dass sie sich selbst verwerfen soll, indem sie ihren Darstellungsstatus ändert. Dazu fügen Sie zunächst eine neue Umgebungseigenschaft zu der Ansicht hinzu, die Du schliessen möchtest:
@Environment(\.presentationMode) var presentationMode
Mit folgender Zeile schliesst Du dann schlussendlich die View:
self.presentationMode.wrappedValue.dismiss()
Die andere Möglichkeit besteht darin, eine Bindung in die gezeigte View zu übergeben, so dass der Wert der Bindung wieder auf „false“ geändert werden kann.
Wenn Du z.B. ViewA mit einer @State-Eigenschaft wie dieser hatten:
@State var showingNewUserView = false
Du kannst Deine NewUserView mit einem Sheet wie diesem präsentieren:
.sheet(isPresented: $showingNewUserView) { NewUserView() }
Bei der Verwendung des Bindungsansatzes für das Verwerfen einer View würden Du Deine Zielansicht – die als Sheet angezeigt wurde – so modifizieren, dass sie eine Bindung desselben Typs hat, der für die Präsentation der View verwendet wurde.
In unserem obigen Beispiel haben wir das Sheet präsentiert, als die View von NewUserView den Wert true hatte, also müssten wir eine boolesche Bindung zu NewUserView hinzufügen, wie hier:
@Binding var isPresented: Bool
Wenn Du möchtest, dass NewUserView sich selbst beendet, setze einfach isPresent zurück auf false, so wie hier:
self.isPresented = false
Nun zum wichtigen Teil: Wenn Du Deine Zielansicht (in diesem Beispiel NewUserView) erstellst, musst Du diesen Datenfluss als Teil Deines Initialisierers übergeben, damit Swift weiß, mit welchem Booleschen es arbeitet.
Du könntest also Deinen bisherigen Sheet-Code durch diesen ersetzen:
.sheet(isPresented: $showingNewUserView) { NewUserView(isPresented: self.$showingNewUserView) }
Bei diesem Ansatz veranlasst SwiftUI diese beiden Ansichten, denselben booleschen Wert zu lesen und zu schreiben, d.h. wenn NewUserView den booleschen Wert wieder auf „false“ setzt, wird das Blatt automatisch ausgeblendet.