Kategorien-Archiv Xcode Swift FR

VonTobias Stephan

Pour des raisons que je ne peux pas expliquer, la toile (de Canvas) n’était tout simplement plus affichée dans un fichier SwiftUI. La recherche sur Google n’a pas aidé non plus. J’utilise Catalina 10.15. Après tout, ça marchait avant. Dans le même projet avec d’autres fichiers SwiftUI, l’aperçu a également été affiché. Je recommande donc une solution de contournement rapide. Copier + Coller est la solution ici. Il suffit de créer un nouveau fichier et de supprimer l’ancien. Insérez à nouveau le code source et pouf… la prévisualisation est de retour. Bien sûr, vous devez vérifier si la toile est montrée.

Avec le menu Éditeur + Toile, la toile peut être affichée ou masquée. Une autre possibilité est la
Combinaison de touches : ALT – Commandement – RETURN

Ici dans l’image, vous pouvez cliquer sur le symbole en haut à droite, 2ème en partant de la droite.

VonTobias Stephan

SwiftUI TableView ListView example sample code project

À mon avis, SwiftUI est un jalon absolu dans le développement de logiciels. Il faut certes du temps pour s’habituer à cette nouvelle façon de se développer, mais le temps que vous gagnez sur d’autres projets peut être bien investi. Vous trouverez ici un exemple simple de SwiftUI TableView. L’exemple de projet peut être téléchargé et utilisé librement. Le projet ne contient délibérément pas plus, afin que les fonctions essentielles contribuent à la compréhension.

Download XCode Sample Project.

Il est assez impressionnant de voir le peu de lignes de code que l’on peut créer un TableView / ListView avec SwiftUI. Il suffit de créer un nouveau projet et de s’assurer que SwiftUI est sélectionné comme interface utilisateur.

SwiftUI Interace selektieren

Bien sûr, il vous faut encore 3 images pour cet exemple, elles sont également incluses dans l’exemple de projet.

Assets für die Bilder in der Liste

Le code réel du projet.

import SwiftUI

struct ContentView: View {
    var oListArray: [oListenEntries] = testData
    var body: some View {
        List(oListArray) { item in
            Image(item.imageName).resizable().frame(width: 32.0, height: 20.0)
            VStack(alignment: .leading){
                Text(item.make)
                Text(item.model)
                    .font(.subheadline)
                    .foregroundColor(Color.gray)
            }
        }
    }

    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView(oListArray: testData)
        }
    }
}

Voici le code du tableau sous-jacent. Pour cela, j’ai créé une vue SwiftUI avec le nom oListEntries.swift.

import SwiftUI

struct oListenEntries : Identifiable {
    var id = UUID()
    var make: String;
    var model: String;
    var imageName: String { return make }
}

let testData = [
    oListenEntries(make: "Flaschenhalter", model: "für Balkon oder Pool"),
    oListenEntries(make: "Pooladapter", model: "32 mm auf 12 mm"),
    oListenEntries(make: "Sektglashalter", model: "schwimmend")
]
VonTobias Stephan

Swiftui tabbar selecteditem

Lors de mes premières tentatives avec Swift UI, j’ai essayé désespérément de trouver comment sélectionner l’onglet actif par programmation. L’astuce est dans la reliure.

@State public var selection = 0

En cliquant sur le bouton, la sélection indique la valeur un. Comme la sélection est directement liée à la barre d’onglets, l’élément actif de l’onglet change selon les besoins.

Button("Go",action: {self.selection = 1})

La liaison est le jeton d’accès que vous pouvez passer pour permettre un accès direct en lecture et en écriture à la valeur sans en accorder la possession (au sens de conserver un type de référence) ou la copie (pour un type de valeur).

Lorsque l’utilisateur sélectionne un onglet dans l’affichage des onglets, il modifie la valeur unilatéralement par liaison et affecte le .tag(…) correspondant à la variable Tab sélectionnée. Cela fonctionne de la même manière pour @State et ObservableObject.

Le programmeur peut également attribuer une valeur à cette variable Tab sélectionnée à tout moment – et le TabView bascule immédiatement l’onglet affiché.

C’est la clé de la navigation programmatique dans SwiftUI.

Voici un exemple que vous pouvez copier / coller directement pour jouer avec.

import SwiftUI

struct ContentView: View {
    @State public var selection = 0

    let defaults = UserDefaults.standard

    var body: some View {
        TabView(selection: $selection){
            VStack {
                Text("First View")
                Button("Go",action: {self.selection = 1})
            }
            .font(.title)
            .tabItem {
                VStack {
                    Image("first")
                    Text("First")
                }
            }
            .tag(0)
            Text("Second View")

                .font(.title)
                .tabItem {
                    VStack {
                        HStack{
                            Image("second")
                            Text("Second")
                        }
                    }
            }
            .tag(1)
        }
    }
}



struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
VonTobias Stephan

Swift Substring to String

Ces opérations sur les cordes en Swift peuvent vous rendre fou même si vous êtes habitué à un simple à partir du C#. C’est pourquoi je me suis penché sur la question et j’ai rassemblé un peu de ça. Ceci a été testé avec le Swift 5.1

  • startIndex est l’indice du premier caractères
  • endIndex est l’index après le dernier caractère
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let str = "Hello, playground"
        print(str[str.startIndex]) // H
        //print(str[str.endIndex])   // error: after last character

        let rangeStartToEnd = str.startIndex..



before fait référence à l'index du caractère qui précède directement l'index spécifié.

// character
let index = str.index(before: str.endIndex)
str[index] 

// range
let range = str.startIndex..



La valeur OffsetBy peut être positive ou négative et part de l'indice spécifié. Bien qu'il soit de type String.IndexDistance, vous pouvez passer une valeur Int.

// character
let index = str.index(str.startIndex, offsetBy: 7)
str[index]

// range
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..



Le limitedBy est utile pour s'assurer que le décalage n'entraîne pas le dépassement des limites de l'indice. C'est un indice limite. Comme il est possible que le décalage dépasse la limite, cette méthode renvoie une option. Il retourne zéro si l'indice est en dehors des limites.

if let index = str.index(str.startIndex, offsetBy: 7, limitedBy: str.endIndex) {
    str[index]
}

Si le "offset" avait été 77 au lieu de 7, l'énoncé if aurait été sauté.

Warum denn nun der ganze Umstand?

Il serait beaucoup plus facile d'utiliser un index Int pour les cordes. La raison pour laquelle vous devez créer un nouveau String.index pour chaque chaîne est que les caractères dans Swift ne sont pas tous de la même longueur sous le capot. Un seul caractère Swift peut être constitué d'un, deux ou même plusieurs points de code Unicode. Par conséquent, chaque chaîne unique doit calculer les indices de ses caractères.

Il est possible de cacher cette complexité derrière une extension d'index Int, mais j'hésite à le faire. Il est bon de se rappeler ce qui se passe réellement.

Une extension utile

L'Extenson suivant doit être ajouté sous votre classe dans le code. Cette extension vous offre la possibilité de déterminer l'index d'une chaîne entière dans une chaîne de caractères. Dans mon exemple "terre".

Les opérations sur les chaînes de caractères sont donc traitées par le biais d'indices et de plages. L'indice n'est donc pas une simple variable integer.

extension StringProtocol {
    func index(of string: S, options: String.CompareOptions = []) -> Index? {
        range(of: string, options: options)?.lowerBound
    }
    func endIndex(of string: S, options: String.CompareOptions = []) -> Index? {
        range(of: string, options: options)?.upperBound
    }
    func indices(of string: S, options: String.CompareOptions = []) -> [Index] {
        var indices: [Index] = []
        var startIndex = self.startIndex
        while startIndex < endIndex,
            let range = self[startIndex...]
                .range(of: string, options: options) {
                indices.append(range.lowerBound)
                startIndex = range.lowerBound < range.upperBound ? range.upperBound :
                    index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
        }
        return indices
    }
    func ranges(of string: S, options: String.CompareOptions = []) -> [Range] {
        var result: [Range] = []
        var startIndex = self.startIndex
        while startIndex < endIndex,
            let range = self[startIndex...]
                .range(of: string, options: options) {
                result.append(range)
                startIndex = range.lowerBound < range.upperBound ? range.upperBound :
                    index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
        }
        return result
    }
}