Le novità del linguaggio Swift 5

le novità del linguaggio swift 5

Apple ha appena rilasciato la versione 5 del nostro linguaggio di programmazione preferito, introducendo diverse interessanti novità.

Vediamole insieme 💪

ABI Stability

La novità più importante consiste nell’aver introdotto l’ABI Stability (ho accennato l’argomento in questo articolo).

Ma, che vantaggi porterà a noi developers?

D’ora in poi, un’app compilata con Swift 5 potrà comunicare con una libreria compilata con un’altra versione di Swift.

In passato potrà esserti capitato che, dopo un’aggiornamento di Swift, la tua applicazione che sfruttava CocoaPods non compilasse più, costringendoti ad aggiornare manualmente i Pods.

Questo scenario in futuro non potrà mai più ripresentarsi!

Inoltre, le app presenti sull’App Store compilate con il linguaggio Swift 5 avranno una dimensione minore perché non incorporeranno più le Swift standard libraries, in quanto saranno incluse in iOS.

String literals

Swift 5 introduce un nuovo modo di creare le stringhe, usando il simbolo # come delimitatore.

Questo vuol dire che, non dovrai più usare il backslash (il carattere “\”) per inserire alcuni caratteri speciali (come ad esempio \n, \t, \”).

Nel caso in cui dovessimo inserire un asterisco all’interno di una stringa, basterà delimitarla con un asterisco in più.

Vediamo alcuni esempi:

print(#""I think the things you regret most in life are the things you didn’t do." - Steve Jobs"#)

print(##"Swift 5 is #awesome"##)

print(#"One plus one is \#(1 + 1)"#)

let regex = #"https:\/\/(www\.)*xcoding\.it"#

Il tipo Result

Questo nuovo tipo è un enum composto da due cases: success e failure, entrambi implementati usando i generics.

Tuttavia, failure dovrà essere conforme al tipo Error. Questo nuovo tipo potrebbe aiutarti a gestire meglio gli errori in una situazione complessa, come ad esempio una chiamata ad una API.

Facciamo un esempio:

Ipotizza di dover implementare una chiamata ad un servizio che ti restituisce il saldo del tuo conto corrente.

enum NetworkError: Error {
    case unauthorized
}

func getBalance(completion: @escaping (Result<Decimal, NetworkError>) -> Void) {
    // ...
    URLSession.shared.dataTask(with: request) { data, response, error in
        guard response.statusCode != 401 else {
            completion(.failure(.unauthorized))
        }
    
        let balance: Decimal = getBalance(fromData: data)
        completion(.success(data))
    }
}

getBalance() { result in
    switch result {
        case .success(let balance):
            print("Your balance: \(balance) €.")
        case .failure(let error):
            if error == .unauthorized {
                print("Unauthorized!")
            }
    }
}

String interpolation

Debuggando, ti sarà sicuramente capitato di stampare un oggetto in console, ed avrai notato che, nel caso di una classe, non vengano restituite informazioni particolarmente interessanti.

Per ovviare a questo problema, potrai estendere il metodo appendInterpolation della classe String.StringInterpolation aggiungendo le tue classi:

class Person {
    var name: String
    var surname: String
}

extension String.StringInterpolation {
    mutating func appendInterpolation(_ value: Person) {
        appendInterpolation("\(value.name) \(value.surname)")
    }
}

Ma qual è la differenza con CustomStringConvertible?

È semplice, con appendInterpolation potrai aggiungere tutti i parametri che ti serviranno:

extension Person {
    enum PrintStyle {
        case full
        case nameOnly
    }
}

extension String.StringInterpolation {
    mutating func appendInterpolation(_ value: Person, printStyle: Person.PrintStyle) {
        if printStyle == full {
            appendInterpolation("\(value.name) \(value.surname)")
        } else {
            appendInterpolation("\(value.name)")
        }
    }
}

Gestire enum futuri

In passato, quando ti trovavi a gestire degli enum con possibili sviluppi futuri, avresti utilizzato la keyword default.

Ora invece, grazie all’introduzione della keyword @unknown default, hai la possibilità di gestire i casi di enum ad oggi inesistenti, triggerando un warning in fase di compilazione.

Opzionali nidificati

Finalmente con l’utilizzo della keyword try? in Swift 5 non ci verrà più restituito un doppio opzionale (se non triplo), bensì un singolo opzionale.

Questo potrebbe succederti, ad esempio, se provassi a chiamare un metodo marcato come throws su un oggetto opzionale:

func getBalance(_ person: Person) throws -> Decimal {
    if let bankAccount = person.bankAccount {
        return bankAccount.balance
    } else {
        throw NSError(domain: "it.xcoding.error", code: -102, userInfo: nil)
    }
}

let balance: Decimal = try? getBalance(person) // person in questo caso sarà opzionale

print(type(of: balance) // Swift 4.2 -> Decimal??
print(type(of: balance)) // Swift 5 -> Decimal?

compactMapValues e dizionari

Questo metodo ti permette di creare un nuovo dizionario a partire dall’originale escludendo gli opzionali, ad esempio:

let grades: [String, String] = [
"Emanuele": "18",
"Giorgio": "25",
"Anna": "Non classificato"
]

let passed: [String, Int] = grades.compactMapValues { Int.init }
// il nuovo dizionario creato escluderà Anna

isMultiple(of:)

Questo nuovo metodo ti permette di verificare che un numero sia multiplo di un altro numero, ad esempio:

if myNumber.isMultiple(of: 2) {
    print("Il numero \(myNumber) è pari")
}

Ovviamente, scrivere:

if myNumber % 2 == 0

Sarebbe stata la stessa cosa, ma questo nuovo metodo rende il codice più leggibile.

Le novità del linguaggio Swift 4.2

Le novità del linguaggio swift 4.2

Come di consueto, assieme ad Xcode 10 (di cui puoi vedere le novità nell’articolo di Peppe), Apple alla WWDC ha ufficialmente presentato anche la nuova versione del linguaggio Swift 4.2.

Swift 4.2?

Assieme ad iOS 12, non dovrebbe essere rilasciata una major release di Swift come tutti gli altri anni?

No, quest’anno la Apple ha deciso di prendersi un po’ più di tempo e rilasciare Swift 5.0 ad inizio 2019, per poter raggiungere la stabilità delle ABI (Application Binary Interfaces).

Attualmente, Swift non è ancora “ABI Stable”, quindi tutti i file binari delle App incorporano la versione delle Swift Dynamic Libraries con la quale il codice è stato compilato (ad esempio, se hai compilato un’App usando Swift 4.1, il binario incorporerà SOLO le librarie di Swift 4.1, e così via dicendo).

Questo perché Swift non convive ancora con iOS, ma viene “definito” assieme ai file binari dell’App.

Ma veniamo a noi, e vediamo le novità del linguaggio Swift 4.2.

Nota bene: attualmente, Swift 4.2 è incluso solamente nella beta di Xcode 10, la versione finale verrà rilasciata a settembre assieme ad iOS 12. Inoltre, da qui al rilascio definitivo, alcune funzionalità potrebbero cambiare, quindi torna qui tra un paio di mesi per scoprire gli ultimi cambiamenti!

Il protocollo CaseIterable

Grazie a questo nuovo protocollo, sarà possibile rendere gli enum iterabili! Ti basterà aggiungere la conformità al protocollo CaseIterable ed il gioco sarà fatto:

enum UserRole: CaseIterable {
    case user, moderator, admin
}

Verrà generato la computed property allCases, che in questo caso restituirà un array di UserRole.

Nell’eventualità volessi personalizzare la allCases puoi ridefinirla manualmente:

enum UserRole: CaseIterable {
    case user, moderator, admin
    
    static var allCases: [UserRole] {
        return [.user, .moderator, .admin]
    }
}

Questa particolarità è utilissima quando hai un case unavailable. In questo caso il CaseIterable non riuscirà a definire la property allCases e dovrai implementarla manualmente:

enum UserRole: CaseIterable {
    case user, moderator, admin

    @available(*, unavailable)
    case specialCase
    
    static var allCases: [UserRole] {
        return [.user, .moderator, .admin]
    }
}

Le direttive #warning e #error

Sono state introdotte due nuove direttive che generano rispettivamente un warning ed un errore in fase di compilazione:

#warning("Rendere la classe Author conforme al protocollo Equatable")
#error("Cancellare questa linea di codice temporanea!")

Nuove direttive

Questo ti permetterà di eliminare o dar più forza ed importanza a quei commenti “TODO: ….”.

Nuova API per la generazione di variabili casuali

Il linguaggio Swift 4.2 introduce una nuova API nativa di Swift per la generazione di variabili casuali, migliorando la casualità dell’output rendendola veramente casuale. Basterà chiamare la proprietà random del tipo di dato da randomizzare in questo modo:

let randomInt = Int.random(in: 1...10)
let randomDouble = Double.random(in: 1...10)
let randomFloat = Float.random(in: 0...1)
let randomBool = Bool.random()

Inoltre, gli Array hanno guadagnato dei comodissimi metodi, shuffle(), shuffled() e randomElement():

var authors = ["Peppe", "Emanuele", "Matteo", "Sara", "Luca"]
// per mischiare gli elementi di un Array
authors.shuffle()
// per creare una copia mischiata di un Array
let shuffledAuthors = authors.shuffled()
// per selezionare un elemento casuale da un Array
print("Un saluto alla community di xCoding.it da " + authors.randomElement()!)

Nota che quest’ultimo metodo restituisce un opzionale, perché potrebbe essere usato su un Array vuoto.

Il metodo removeAll delle collezioni

Il metodo removeAll, introdotto per tutti i tipi di Collection, permette di rimuovere in modo efficiente gli elementi di una Collection che non soddisfino i requisiti presenti nella closure, come ad esempio:

var authors = ["Peppe", "Emanuele", "Matteo", "Sara", "Luca"]
authors.removeAll { $0.count <= 5 }
// authors ora conterrà solo le stringhe di 6 o più caratteri

Il metodo allSatisfy delle sequenze

Al contrario del metodo removeAll per le collezioni, la funzione allSatisfy restituisce una sequenza di elementi che soddisfino una determinata condizione:

var numbers = [4, 8, 15, 16, 23, 42]
let evenNumbers = numbers.allSatisfy { $0 % 2 == 0 }
// evenNumbers conterrà solo i numeri pari presenti nell'Array numbers

Ma come, questi ultimi due nuovi metodi sono inutili! Potevo fare già tutto ciò con filter 😎”
Hai ragione, ma rispetto alla funzione filter, i nuovi metodi sono ottimizzati per eseguire l’operazione molto più velocemente.

Bool.toggle()

Infine, è stato aggiunto un simpatico metodo per invertire il valore di un Bool, quindi anziché scrivere:

var isActive = false
isActive = !isActive

Potremo scrivere:

isActive.toggle()

Comodo, no?

Conclusioni

Ovviamente queste sono solo una piccola parte di tutte le modifiche apportate a Swift, quindi per vedere tutte le modifiche che Apple ha apportato a Swift 4.2, dai un’occhiata al changelog ufficiale.

Nell’eventualità mi volessi far presente altre modifiche importanti, scrivimi pure un commento in qui sotto.

Mentre se sei interessato alle novità di Xcode 10 puoi leggere questo nostro articolo e se vuoi rimanere aggiornato su tutte le novità presentate alla WWDC 2018, ti consiglio di leggere tutti gli articoli che trovi su iSpazio o sull’app che gli abbiamo sviluppato.

Buona Programmazione!

Come creare un account da sviluppatore Apple

Come creare un account da sviluppatore Apple

Hai creato la tua prima applicazione o il tuo primo sticker pack e vuoi pubblicarli sull’Apple Store?

Innanzitutto, il primissimo passo da compiere è quello di creare un ID Apple. Lo dovresti aver creato quando hai comprato l’iPhone o il Mac. Quindi darò per scontato che tu ne abbia già uno, in caso contrario clicca qui.

Account pronto? Allora vediamo come creare un account da sviluppatore Apple!

Il portale sviluppatori

Collegati al portale degli sviluppatori Apple, che contiene un sacco di informazioni utili per tutti coloro che vogliono avvicinarsi al mondo della programmazione Apple.

come-creare-un-account-sviluppatore-apple

Dentro il portale sviluppatori Apple potrai trovare moltissime risorse utili per lo sviluppo delle tue App, come le linee guida per il design, degli esempi di codice scritti direttamente dagli ingegneri Apple e tutta la documentazione relativa alle API di iOS, tvOS, watchOS e macOS.

L’importante è che non ci abbandoni :(

Ma non perdiamo tempo, e procediamo con l’iscrizione per diventare uno sviluppatore Apple.

Clicca su Account in alto a destra, ed effettua il login con il tuo ID Apple. Arrivato a questo punto, dovrai accettare il contratto legale che ti verrà proposto. Non preoccuparti, la Apple non sta cercando di prendere possesso della tua anima facendoti firmare questo contratto!

Contratto di licenza

Et voilà, sei appena diventato uno sviluppatore Apple ufficiale!

Calma, calma, non hai ancora finito! Ti mancano ancora un paio di cose da fare prima di poter pubblicare un’app sull’App Store.

Apple Developer Program

La prossima cosa da fare è iscriversi all’Apple Developer Program.

Developer Account

Adesso viene la parte più lunga e meno divertente, ovvero la compilazione di tutti i moduli relativi ai dati personali del Developer, come le informazioni sui contatti e la scelta se iscriverti come privato oppure come azienda.

Completa tutti i campi richiesti, finché non arriverà la parte più dolorosa per il tuo portafogli, ovvero il pagamento della quota annuale di 99€ per entrare a far parte dell’Apple Developer Program.

Inserisci i dati per il pagamento, e scegli se attivare il rinnovo automatico del contratto, ed il relativo pagamento con cadenza annuale. Non preoccuparti, potrai decidere in seguito se disattivarlo o attivarlo.

Infine, non ti resta che aspettare!

La finalizzazione dell’acquisto potrebbe metterci fino a 48 ore, ma solitamente l’ordine verrà evaso nel giro di un’oretta.

Dopo che avrai ricevuto la mail che ti confermerà l’iscrizione all’Apple Developer Program, avrai l’accesso completo alla pagina del tuo account. Da ora in poi, potrai anche scaricare i software beta per i tuoi devices:

Developer Program Portal

Questa pagina ti darà accesso principalmente a tre sezioni.

  1. La gestione dei certificati: dove potrai creare e gestire tutti i certificati necessari per la pubblicazione delle tue App, aggiungere nuove App ed registrare i tuoi dispositivi Apple. Fortunatamente con l’aggiornamento ad Xcode 8, è diventato tutto molto più semplice per quel che riguarda i certificati;
  2. iTunes Connect: qui potrai gestire le tue App, a partire dal beta testing con TestFlight fino alla pubblicazione sull’App Store;
  3. La Dashboard di CloudKit: che ti permetterà di gestire lo spazio ed i dati di CloudKit. Per maggiori informazioni ti consiglio di dare un’occhiata al tutorial di Giuseppe.

Considerazioni

Semplice, veloce ed indolore. Apple ha lavorato moltissimo sulla semplificazione dei passaggi d’iscrizione e pubblicazione di un’applicazione sull’Apple Store.

Adesso non ti resta che iniziare a sviluppare come se non ci fosse un domani, e pubblicare le tue creazioni sull’App Store! A tal proposito non posso che consigliarti di dare uno sguardo ai nostri:

Già che ci siamo ti linko il tutorial di Gianvittorio su come pubblicare un’app sull’App Store, potrebbe esserti utile ;)

Se qualcosa non dovesse esserti chiaro, non farti problemi a lasciare un commento qui sotto.

Buona programmazione!

changelog

  • 7/11/2016 – Aggiunto il changelog.

3D Touch e Quick Actions con il linguaggio Swift

Con l’iPhone 6S, e di conseguenza con iOS 9 e successivi, Apple ha introdotto una nuova tecnologia chiamata 3D Touch, che utilizza un sensore presente sul vetro del tuo telefono per rilevare la pressione del dito sul display.

Il 3D Touch si discosta completamente dalle gesture precedenti, in quanto, non si tratta di una normale pressione (cioè un click o click continuo sullo schermo) bensì di un click dove l’utente deve aumentare la pressione contro lo schermo per poter attivare il sensore del 3D Touch.

Esistono due particolari applicazioni di questa nuova funzionalità presente solo negli iPhone 6S/6S Plus in su.

  • Le Quick Actions, cioè dei menu che compaiono attivando il 3D Touch sull’icona dell’applicazione. Grazie a questi menu sarai in grado di accedere velocemente a sezioni della tua applicazione.
  • Preview o 3D Touch in app, dove grazie a questa tecnologia puoi visualizzare un componente dell’applicazione senza entrarci realmente. Per esempio, puoi visualizzare il ViewController di destinazione di un segue senza realmente attivarlo. Oppure, aprire e visualizzare un’email in anteprima direttamente dalla lista delle email ricevute.

3D Touch e Quick Actions con il linguaggio Swift

In questo tutorial, voglio parlarti del 3D Touch e Quick Actions con il linguaggio Swift. Per seguire questo tutorial è necessario che tu sappia già creare applicazioni. A tal proposito ti consiglio i due corsi di sviluppo app e se vuoi cominciare bene, segui questi consigli.

Come creare una Quick Actions con Swift

Per creare una Quick Action ti basta modificare il file info.plist della tua App. Tieni a mente che è possibile creare al massimo quattro Quick Actions!

Inizia ad aprire il file Info.plist, ed aggiungi una chiave alla lista premendo il tasto + vicino a Information Property List:

Aggiunta Quick Actions

Modifica il nome del nuovo elemento in UIApplicationShortcutItems e cambia il tipo in Array. Successivamente aggiungi un elemento per ogni Quick Action che vuoi creare (ricorda, creane al massimo quattro!) e cambia il tipo in Dictionary.

Infine, per ogni elemento che hai creato, devi aggiungere questi due campi (di tipo String), indispensabili per il corretto funzionamento:

  1. UIApplicationShortcutItemType: una stringa che identifica univocamente le Quick Actions, solitamente si scrive nel seguente formato: com.Organization-Identifier.Quick-Action-name. Io ad esempio ho usato questa sintassi: com.sbeff.aggiungiUtente;
  2. UIApplicationShortcutItemTitle: una stringa che rappresenta il titolo visibile all’utente al momento della pressione sull’icona dell’App.

Oltre a questi due campi puoi aggiungerne altri quattro tutti facoltativi:

  1. UIApplicationShortcutItemSubtitle: come avrai intuito dal nome, è il sottotitolo che verrà inserito sotto il titolo della Quick Action;
  2. UIApplicationShortcutItemIconType: una stringa per impostare una delle icone predefinite che la Apple mette a disposizione, puoi trovare la lista completa a questo indirizzo
  3. UIApplicationShortcutItemIconFile: una stringa da usare nel caso in cui voglia impostare un’icona personalizzata (in questo tutorial non la userai);
  4. UIApplicationShortcutItemUserInfo: un dizionario per memorizzare dei dati (in questo tutorial non lo userai).

Info.plist finale

Bene, adesso sbizzarrisciti pure e crea tutte le Quick Actions che ti vengono in mente e avvia la tua App!

Ovviamente per testarle avrai bisogno di un dispositivo con il 3D Touch (iPhone 6S, 6S Plus e succ). Nota bene: se provi l’app sul simulatore ti potrai domandare come simulare la pressione del 3D Touch. La risposta è semplice: non è possibile attivarlo sull’iOS Simulator a meno che tu non disponga di un Mac con il Force Touch: in quel caso premendo la combinazione di tasti shift-cmd-3 potrai simulare il 3D Touch premendo con forza sul Trackpad.

[mailmunch-form id=”101287″]

Gestire le Quick Actions con Swift

Finalmente è arrivato il momento di scrivere un po’ di codice!

Per gestire le chiamate delle Quick Actions, ti basta aggiungere un metodo nel file AppDelegate.swift, che verrà richiamato ogniqualvolta l’utente le utilizzerà. Il metodo in questione si chiama performActionFor ShortcutItem:

func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
     //questo codice verrà eseguito ogni volta che le Quick Actions verranno eseguite   
}

Per capire quale delle tante Quick Actions è stata chiamata è necessario controllare il parametro shortcutItem e più precisamente l’attributo type. Puoi gestire i vari stati con un if-else o con un’istruzione switch (se non te le ricordi, guarda il corso gratuito sul linguaggio swift):

if (shortcutItem.type == "com.sbeff.aggiungiUtente") {

   //gestisci l'aggiunta di un nuovo utente

}

Per rendere l’app un po’ più completa, mostra un’alert ogni volta che viene richiamato il metodo. Nel caso in cui non dovessi capire al 100% il codice che segue, dà un’occhiata al tutorial di Peppe.

All’interno dell’if, aggiungi il seguente codice per far capire un Alert View alla pressione di una Quick Actions:

let controller = UIAlertController(title: "App lanciata tramite scorciatoia!", message: "Identifier della quick action: \(shortcutItem.type)", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
controller.addAction(action)

DispatchQueue.main.async {
    self.window!.rootViewController?.present(controller, animated: true, completion: nil)
}

Il DispatchQueue.main.async manda in esecuzione il codice al suo interno in un thread sulla main queue ovvero sul thread che gestisce l’interfaccia grafica dell’applicazione.

Questo è necessario in quanto, il codice che stai scrivendo, si trova all’interno dell’AppDelegate che non è un oggetto grafico bensì un gestore dell’applicazione. Il metodo present, infine, mostrerà l’alert dato che verrà invocato nel rootViewController dell’applicazione (ovvero il VC che è stato assegnato come “Is Initial View Controller”).

Avvia l’App. Noterai che per ogni Quick Action selezionata verrà mostrata un’Alert con il titolo corrispondente alla Action scelta.

Considerazioni

Hai ufficialmente finito questo tutorial! Se qualsiasi qualcosa non dovesse esserti chiara, fammelo sapere nei commenti oppure sul nostro gruppo Facebook o Slack.

 

Buona programmazione!

Changelog

  •  20/01/2017 – Aggiunto il changelog. Tutorial aggiornato ad Xcode 8 e linguaggio Swift 3.

Pinch e Tap to Zoom in Swift. Come zoommare una immagine

Hai una galleria d’immagini e hai bisogno di zoommare le tue immagini?

Niente paura! A differenza di quello che si può pensare eseguire lo zoom di un’immagine con il linguaggio Swift è un vero e proprio gioco da ragazzi.

Il processo è reso così semplice grazie ad un piccolo aiuto fornito da un oggetto speciale chiamata Scroll View (un contenitore di view che può essere scrollato e zoommato). All’interno della Scroll View, che è l’effettivo burattinaio dello zoom, verrà inserita un’image view la quale conterrà l’immagine dal zoommare.

Più facile a farsi che a dirsi! Vediamo subito come implementare il Pinch e Tap to Zoom in Swift.

Scroll View e Image View

Apri Xcode e crea un nuovo progetto. Seleziona “Single View Application”, poi assegna un titolo a piacere ed imposta il linguaggio Swift. Dallo storyboard aggiungi una Scroll View, allargala a tutto schermo ed aggiungi le constraints necessarie. Successivamente, trascina una Image View dentro la Scroll View appena creata.

Ti starai chiedendo: “perché mai dovrei aggiungere una immagine in una Scroll View?!” Perché è il modo più semplice per gestire lo zoom di un’immagine. Anche qui aggiungi le solite 4 constraints ai margini, più altre 2 per centrare il contenuto dell’immagine.

Aggiunta della Scroll View e della Image View Fatto ciò, imposta l’immagine dell’Image View con una di tuo gradimento, io ho usato il logo di xCoding. Cambia l’attributo “Mode” su “Aspect Fit” per evitare che l’immagine venga rappresentata nel modo sbagliato.

Per aggiungere un’immagine al progetto, apri la cartella Assets.xcassets dal Project Navigator, seleziona il file desiderato dal Finder e trascinalo su Xcode (sotto “AppIcon”) per creare un nuovo asset di immagini.

aggiunta-immagine

Successivamente modifica l’attributo “Image” della Image View con il nome dell’immagine appena aggiunta.

Hai quasi completato la Storyboard! Crea un IBOutlet per entrambi gli elementi (io li ho chiamati “image” e “scroll”) ed imposta il delegate della Scroll View trascinandola sul quadratino giallo del View Controller.

Creazione del delegate

Il Pinch to Zoom

Bene, hai finito con l’interfaccia grafica! È arrivato il momento di passare al codice.

Per prima cosa aggiungi il protocollo UIScrollViewDelegate alla tua classe. Questo protocollo ti permetterà di aggiungere i metodi per rendere la tua immagine “zoommabile”:

import UIKit

class ViewController: UIViewController, UIScrollViewDelegate {

    @IBOutlet weak var scroll: UIScrollView!
    @IBOutlet weak var image: UIImageView!

Successivamente, nel metodo viewDidLoad, aggiungi le seguenti proprietà alla tua Scroll View:

override func viewDidLoad() {

        super.viewDidLoad()
        self.scroll.minimumZoomScale = 1.0
        self.scroll.maximumZoomScale = 3.0
        
}

Come sicuramente avrai intuito, i parametri minimumZoomScale e maximumZoomScale regolano rispettivamente le dimensioni minime e massime che l’immagine può assumere durante lo zoom (in realtà non dipendono dall’immagine che inserirai, bensì qualsiasi elemento che inserirai all’interno della tua ScrollView è influenzato da questi valori). Un valore di 1.0 sta a significare nessun cambiamento di scala, mentre un valore di 3.0 significa che il contenuto potrà essere ingradito fino a tre volte la dimensione attuale.

Ovviamente puoi impostare i valori che preferisci, in base alle tue esigenze e soprattutto in base alle dimensioni dell’immagine. Più è alta la risoluzione, più potrai zoommare senza creare sgranature.

[mailmunch-form id=”101287″]

Infine, dato che hai impostato il View Controller come delegate della Scroll View (cioè sarà il View Controller a gestire i metodi della Scroll View), aggiungi il metodo viewForZoomingInScrollView. Questo metodo, presente nel protocollo UIScrollViewDelegate, viene richiamato ogniqualvolta l’utente esegue uno zoom con le dita sulla Scoll View. Il metodo viewForZooming(in scrollView: UIScrollView) restituisce una UIView, nel nostro caso restituiremo la Image View zoommata:

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        
        return image
        
}

Bene, è arrivato il momento di compilare ed eseguire il progetto della tua App! Se sei utilizzando il simulatore, premi alt + click per simulare la gesture del pinch to zoom.

Pinch to Zoom, parte 1

 

Implementazione del Tap to Zoom

Adesso è arrivato il momento di andare un po’ oltre e di vedere come zoommare l’immagine eseguendo un doppio Tap su un punto dello schermo. Per sbloccare tale funzionalità hai bisogno di un GestureRecognizer, cioè un particolare oggetto che riesce ad intercettare gli eventi di tocco e altri sullo schermo. Mi prenderò la briga di dare il loro utilizzo per scontato, se vuoi ampliare queste conoscenze a riguardo, nel corso di sviluppo app iOS di Giuseppe Sapienza c’è un’intera lezione a riguardo.

Procediamo! Inserisci il seguente codice nel metodo viewDidLoad:

//1
let tap = UITapGestureRecognizer(target: self, action: #selector(ViewController.zoom))
        
//2
tap.numberOfTapsRequired = 2

//3        
scroll.addGestureRecognizer(tap)

Analizziamo il codice appena inserito (I numeri si riferiscono al commento che trovi nel codice qui sopra):

  1. Crea una costante per la gestione del UITapGestureRecognizer. Il recognizer utilizza come funzione di riferimento il selettore ViewController.zoom (attenzione, il nome del mio ViewController potrebbe non essere uguale al tuo), il quale avrà un parametro che come tipo di dato sarà un UITapGestureRecognizer, cioè l’oggetto che ha invocato il metodo.
  2. Cambia il numero di tap richiesti per attivare il recognizer e di conseguenza il metodo zoom.
  3. Aggiungi la gestureRecognizer, contenuta nella costante “tap”, alla Scroll View.

D’ora in poi, quando premerai velocemente due volte sulla Scroll View verrà richiamata la funzione zoom, che non hai ancora creato. Subito dopo il viewDidLoad, aggiungi il metodo zoom(sender: UITapGestureRecognizer) cioè la funzione che verrà richiamata quando l’utente premerà due volte velocemente sulla scroll view:

func zoom(sender: UITapGestureRecognizer) {
        
        //1
        if (scroll.zoomScale < 1.5) {
            
            //2
            scroll.setZoomScale(scroll.maximumZoomScale, animated: true)
        
        } else {
            
            //3
            scroll.setZoomScale(scroll.minimumZoomScale, animated: true)
            
        }
        
}

Analizziamo nuovamente il codice:

  1. Controlla il valore di zoom attuale. Nel caso in cui l’immagine non sia ancora stata zoommata del 150% rispetto all’originale, attiva il codice dentro l’if.
  2. Nel caso in cui la condizione sopra riportata sia vera, il metodo setZoomScale, zoomma l’immagine del valore massimo impostato alla tua scrollView (ad inizio tutorial hai messo 3 come maximumZoomScale).
  3. Se l’immagine è stata già zoommata, cioè l’if è a condizione false, viene attivato l’else che riporta la scroll al suo valore di minimumZoomScale.

Conclusioni

Nel codice che ti ho lasciato, avrai notato che a differenza delle Image View presenti su iOS, la tua funzione di zoom su doppio Tap non zoomma nel punto in cui hai cliccato, bensì sempre al centro. Per ovviare a questo problema, dà un’occhiata al codice nel progetto completo che trovi qui sotto.

Hai ufficialmente finito questo tutorial! Se qualcosa non dovesse esserti chiara, fammelo sapere nei commenti oppure crea una domanda nella sezione “Chiedi aiuto”.

Di seguito trovi il link per scaricare il mio progetto completo, nel caso in cui ti sia perso qualche passaggio.

[sociallocker][wpdm_package id=’43167′][/sociallocker]

Buona programmazione!

Changelog

  • 22/03/2017 – Aggiunto il changelog, tutorial aggiornato ad Xcode 8.3 e Swift 3.1.

Creare una Collection View in Swift

Creare una Collection View in Swift

Ciao, per caso sai cos’è una Collection View? No?Fine prima parte

Sicuramente, senza averla mai riconosciuta, ne avrai già vista almeno una nel tuo iPhone! È il metodo che usa l’app “Foto” per raccogliere le
immagini presenti nel rullino. Una Collection View, è un sistema per rappresentare degli elementi (che possono essere delle immagini, delle label, ecc) sotto forma di una “griglia”, composta da righe e colonne.

Possiamo dire che le Collection View sono cugine delle famose Table View. Infatti, vedrai che i metodi usati per implementarle sono molto simili tra di loro. Aspetta! non sai cosa sia una Table View? Dai un’occhiata al tutorial di Peppe.

La differenza con le Table View sta tutta nel sistema utilizzato per la rappresentazione dei dati. Se le Table View utilizza delle Celle che vengono impilate tutte una sotto l’altra, le Collection View utilizzano sempre una Cella ma che viene collocata in riga e colonna in base allo spazio messo a disposizione dal display.

Nell’immagine di lato, cioè l’app che creerai a fine tutorial, la collection view è formata da una cella di dimensione uguale alla metà del display dell’iPhone 6S. Tale dimensione permette alla Collection View di mettere due Celle in un’unica riga.

Come ci riesce? non spetta a questo tutorial definirlo. Infatti, una delle potenze della Collection View è che riesce a modificare il numero di colonne in base alla dimensione dello schermo.

Ma vediamo tutto dal punto di vista pratico. Il tutorial è diviso in due sezioni:

  1. La creazione della Collection View con il linguaggio Swift ed il relativo collegamento al codice.
  2. Il segue che permette, grazie ad un click su una determinata cella, di passare ad un nuovo View Controller.

Sei pronto? vediamo come creare una Collection View in Swift!

Aggiungere e modificare una Collection View

Apri Xcode e crea un nuovo progetto. Seleziona “Single View Application”, assegna un titolo, imposta il linguaggio di programmazione su Swift e scegli su quali Device rendere compatibile l’App. Infine, scegli dove salvare il progetto e clicca su “Create”.

New Project

Dal Project navigator, seleziona il file “Main.storyboard”, clicca sul View Controller principale e tramite la la barra del menu di Xcode seleziona Editor > Embed in > Navigation Controller. Assegna un titolo a piacere al Controller appena creato. Questo Navigation Controller, come spiegato in questo tutorial, servirà a gestire la navigazione tra i View Controller.

Embed in navigation controller

Puoi procedere aggiungendo la Collection View tramite l’Object library, poi allargala su tutto lo schermo ed aggiungi le constraints necessarie. Come puoi notare dalla storyboard, Xcode si è accorto che è presente un Navigation Controller e, per questo motivo, crea uno spessore prima della cella.

Aggiunta della Collection View

Fatto ciò, seleziona la Collection View appena creata e tramite il Size inspector modifica a piacere l’altezza e la larghezza della cella (in questo tutorial ho scelto come dimensione 150 e 150). Puoi modificare la larghezza dei margini a 10 (Section Insets), in modo che le celle non siano totalmente attaccate ai bordi dello schermo.

Dimensione margini e cella

Successivamente, seleziona la cella contenuta nella Collection View, e tramite l’Attribute inspector imposta come Identifier “cella”.

Cambiare l'i identifier

Se Identifier ti suona strano, forse è il caso che passi dal tutorial delle table view (ampiamente consigliato prima di passare ad una collection view). In alternativa, se già cominciano ad esserci dei problemi, ascolta il consiglio di Peppe e parti da qualcosa di più semplice.

Dato che utilizzerai una Cella con elementi aggiunti da te, devi creare una nuova classe per la gestione di tale Collection View Cell. Quindi, seleziona File > New File > Cocoa Touch Class e nel campo “Subclass of” seleziona UICollectionViewCell. Per farla riconoscere alla storyboard, seleziona la cella e dall’Identity Inspector, alla voce Class, imposta la classe appena creata.

Aggiungere la classe alla cella

É arrivato il momento di sfogare la tua creatività! Dallo Storyboard personalizza la cella come preferisci, trascinandoci dentro una label, un’immagine, uno slider, o tutto ciò che vuoi!

In questo tutorial, per rendere più semplice possibile la creazione di una Collection Cell, aggiungerai solo un’immagine ed una label. Mi raccomando, non dimenticare di aggiungere le constraints per adattare i vari elementi all’interno della cella! Se vuoi, aggiungi uno sfondo bianco alla label, in modo da rendere il testo più leggibile.

Layout cella

Modifiche fatte?

Il passo successivo è quello di spostarsi nell’Assistant editor e di creare un IBOutlet per ogni elemento aggiunto alla tua cella personalizzata. Quindi, seleziona un elemento per volta e trascinalo verso la classe della tua cella con il tasto destro (oppure presento ctrl + click) per creare l’IBOutlet.

IBOutlet

Hai quasi finito la prima parte! Per completare il lavoro, vai nello Storyboard, apri il Document Outline e selezionando la Collection View trascina col tasto destro, la freccia, verso il View Controller principale, in modo da creare l’outlet per il Delegate e per il Data Source.

Delegate e DataSource

In questo modo dici al View Controller di controllare e gestire il comportamento della tua Collection View.

Dato che Xcode imposta di default lo sfondo delle Collection View sul nero, cambia il colore in bianco, tramite l’Attributes inspector.

Sfondo Collection View

Infine, crea un IBOutlet anche per la Collection View da inserire nel ViewController (chiamalo “collectionView”). Perché te l’ho fatto creare? Lo scoprirai nella seconda parte!

Il codice per il riempimento della Collection View

Modifica il codice della classe (che trovi all’inizio del file “ViewController.swift”) aggiungendo il metodo “Datasource” e “Delegate” appena dichiarati. Il codice che adesso è:

class ViewController: UIViewController {

Dovrà diventare:

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

Non preoccuparti per gli errori che ti segnala Xcode, li sistemeremo subito.

Decidi che tipo di dati vuoi rappresentare nella Collection View. Io prenderò come esempio i prodotti della Apple. Dato che la mia cella include una label ed una immagine, creerò due vettori con le informazioni dei dati da inserire.

Se vuoi, puoi scaricare le immagini che ho utilizzato nel mio progetto qui sotto. Per aggiungerle al progetto, trascinale nel file “Assets.xcassets” presente su Xcode.

[wpdm_package id=’42050′]

Inserisci questo codice prima del metodo viewDidLoad, sia per renderlo accessibile da tutto il View Controller, sia per avere un codice più ordinato. Per riempire le tue celle prenderai i valori da questi array:

var prodottiApple = ["iPhone", "iPad", "MacBook", "Apple Watch"]
var immaginiProdotti = [UIImage(named: "iphone"), UIImage(named: "ipad"), UIImage(named: "macbook"), UIImage(named: "applewatch")]

Ci rimane soltanto una cosa da fare, ovvero aggiungere i due metodi necessari per il corretto funzionamento delle Collection View, che sono i seguenti:

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        
        //questo valore serve per far capire alla Collection View quante celle devono essere visualizzate
        return prodottiApple.count   
    }
    
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cella", forIndexPath: indexPath) as! CollectionViewCell
        
        //impostiamo l'immagine e il testo della label con quelli precedentemente dichiarati nelle due variabili
        cell.imageView?.image = self.immaginiProdotti[indexPath.row]   
        cell.labelNome?.text = prodottiApple[indexPath.row]
        
        return cell
    }

Bene, è arrivato il momento di compilare ed avviare la tua App. Premi il pulsante col simbolo “Play” in alto a sinistra, oppure premi CMD + R ed ammira il risultato!

Fine prima parte

Se hai avviato l’app nel simulatore dell’iPhone 5, avrai notato che il layout non è uguale al mio. Questo accade perché l’iPhone 5 ha una risoluzione inferiore rispetto a quella dei suoi fratelli maggiori, e di conseguenza può rappresentare meno elementi in una schermata.

Et voilà, qui finisce la prima parte del tutorial! Mi raccomando, se ti senti stanco o confuso prenditi una pausa di 10 minuti, e prosegui con la lettura del tutorial.

Prenditi una pausa!

Nel frattempo che sei in pausa, saremmo davvero felici se contribuissi semplicemente con un mi piace o un follow alle pagine di xCoding.it, oppure registrandoti alla newsletter:

[mailmunch-form id=”101287″]

[addtoany]

Grazie davvero :-)

Segue al nuovo View Controller

Eccoci alla seconda parte del tutorial, in cui creeremo un segue che ci permetterà di passare ad un nuovo View Controller contenente maggiori informazioni sull’elemento selezionato. Come? Non hai idea di cosa sia un segue? Dà un’occhiata al seguente tutorial.

Per prima cosa aggiungi un nuovo file, sempre seguendo il procedimento di prima, ma questa volta modifica il campo “Subclass of” in UIViewController, e imposta un nome a piacere.

Dopodiché, apri la StoryBoard ed aggiungi un nuovo View Controller, e personalizzalo come preferisci. In questo tutorial ho scelto di inserire semplicemente una Image View grande quanto tutto lo schermo, ma tu sei libero di aggiungere tutti gli elementi che vuoi! E non dimenticarti di sistemare le constraints :P

Adesso crea un segue dalla Collection View al nuovo View Controller, sempre tenendo premuto il tasto destro, e imposta come metodo “Show”. Fatto ciò, seleziona il segue appena creato, e tramite l’Attributes inspector cambia l’identifier in “mostraImmagine”. Infine, dall’Identity inspector modifica la voce Class nel View Controller che hai creato poco fa.

Creazione segue

Successivamente, crea un IBOutlet per l’immagine a tutto schermo nel nuovo View Controller, chiamandola “sfondo”. Subito dopo, incolla questa riga di codice prima del viewDidLoad per creare una UIImage vuota, che riempiremo tra poco.

var immagine = UIImage()

Infine, modifica il metodo viewDidLoad per impostare l’immagine di sfondo quando la View viene caricata.

override func viewDidLoad() {
        super.viewDidLoad()
        
        immagineGrande.image = immagine
        
        // Do any additional setup after loading the view.
    }

Hai quasi finito! Apri la classe della Collection View ed incolla questo codice, leggendo le spiegazioni per capire cosa faccia ogni singola riga..

   //1
   func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        
       //2
        self.performSegueWithIdentifier("mostraImmagine", sender: self)
        
    }
    
    //3
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        
        //4
        if (segue.identifier == "mostraImmagine") {

            //5                        
            let indexPath = collectionView!.indexPathsForSelectedItems()![0] as NSIndexPath
            
            //6
            let ImmagineVC = segue.destinationViewController as! ImmagineViewController
            
            //7
            ImmagineVC.immagine = self.immaginiProdotti[indexPath.row]!
            
            ImmagineVC.title = self.prodottiApple[indexPath.row]
            
        }
        
    }

Analizziamo il codice appena scritto:

  1. Questo metodo viene chiamato quando viene selezionato un elemento dalla Collection View;
  2. Indichiamo alla View di eseguire il segue denominato “mostraImmagine”;
  3. Questo metodo viene chiamato quando un segue sta per essere eseguito;
  4. Controlliamo che l’identifier del segue in corso corrisponda a “mostraImmagine”;
  5. Recuperiamo l’indexPath, ovvero l’indice che ci permette di rappresentare l’elemento che è stato appena selezionato;
  6. Inizializziamo la variabile contenente le informazioni relative al View Controller che andremo ad aprire;
  7. Impostiamo l’immagine ed il titolo di sfondo del prossimo View Controller;

Sei pronto per il secondo avvio della tua App!
Progetto completo

Conclusioni

Bene, hai ufficialmente finito questo tutorial! Se qualcosa non ti è chiaro fammelo sapere nei commenti, oppure apri un topic nel forum :) Di seguito trovi il link per scaricare il mio progetto completo, nel caso in cui ti sia perso qualche passaggio.

[sociallocker][wpdm_package id=’42070′][/sociallocker]

Buona programmazione!