A partire da iOS 8, le tue applicazioni possono estendere funzionalità e contenuti personalizzati oltre la tua app e renderli disponibili agli utenti mentre utilizzano altre app o il sistema operativo. Un modo per estendere il sistema operativo è creare una tastiera personalizzata.
In questo tutorial ti mostrerò come creare la tua tastiera personalizzata usando Swift e le nuove API di estensione dell'app. Prima di farlo, esamineremo cosa può fare un'estensione di tastiera, cosa non può fare e cosa dovrebbe essere approvato per l'App Store.
Una tastiera personalizzata sostituisce la tastiera di sistema per gli utenti che desiderano funzionalità, come un nuovo metodo di inserimento del testo o la possibilità di immettere testo in una lingua non altrimenti supportata dal sistema operativo.
La funzione essenziale di una tastiera personalizzata è semplice, risponde a tocchi, gesti o altri eventi di input e fornisce testo sotto forma di non attribuito NSString
oggetto nel punto di inserimento del testo dell'oggetto di immissione testo corrente.
Dopo che un utente sceglie una tastiera, rimane come predefinita ogni volta che apre un'app. Per questo motivo la tastiera dovere consentire all'utente di passare a un'altra tastiera.
Esistono due elementi essenziali di sviluppo per ogni tastiera personalizzata:
Fiducia. La tua tastiera personalizzata ti dà accesso a ciò che un utente digita, quindi la fiducia tra te e il tuo utente è essenziale.
Un tasto "prossima tastiera". L'accessibilità che consente all'utente di passare a un'altra tastiera fa parte dell'interfaccia utente di una tastiera; è necessario fornirne uno sulla tastiera. - Guida alla programmazione delle estensioni app
Se è necessario aggiungere solo alcuni pulsanti alla tastiera di sistema, è necessario esaminare le visualizzazioni personalizzate per l'immissione dei dati.
Ci sono alcuni oggetti di input di testo che la tua tastiera personalizzata non è idonea a digitare. Questi includono campi di testo sicuri per l'inserimento di password e oggetti del telefono, come i campi del numero di telefono nel Contatti applicazione.
La tastiera personalizzata non ha accesso alla gerarchia di visualizzazione dell'input, non può controllare il cursore e non è in grado di selezionare il testo. Inoltre, la tastiera personalizzata non può visualizzare nulla sopra la riga superiore. La tastiera di sistema non è limitata da questi vincoli. Ad esempio, mostra un'estensione quando si tocca un tasto per mostrare all'utente quale tasto è stato toccato.
La linea rossa mostra il limite superiore di una tastiera personalizzata.Per impostazione predefinita, una tastiera non ha accesso alla rete e non può condividere file con la sua app contenente. Per abilitare queste funzionalità, imposta il valore di RequestsOpenAccess
chiave nel Info.plist
file su SÌ
. Così facendo espandi la sandbox della tastiera come descritto nella Guida alla programmazione di Apple App Extension.
Se si richiede l'accesso aperto, la tastiera acquisisce le seguenti funzionalità, ciascuna con una responsabilità concomitante:
Assicurati di leggere il documento di Apple Designing for User Trust, che descrive le tue responsabilità per il rispetto e la protezione dei dati degli utenti nel caso in cui richiedi l'accesso aperto.
Nella forma più semplice abbiamo un'applicazione che contiene un'estensione della tastiera e una UIInputViewController
che controlla la tastiera e risponde agli eventi dell'utente.
Il Tastiera personalizzata modello contiene una sottoclasse di UIInputViewController
, che è il controller di visualizzazione principale della tua tastiera. Diamo un'occhiata all'interfaccia per avere un'idea di come funziona.
class UIInputViewController: UIViewController, UITextInputDelegate, NSObjectProtocol var inputView: UIInputView! var textDocumentProxy: NSObject! get func dismissKeyboard () func advanceToNextInputMode () // Questo non fornirà un repository completo del vocabolario di una lingua. // È inteso unicamente per integrare lessici esistenti. func requestSupplementaryLexiconWithCompletion (completionHandler: ((UILexicon!) -> Void)!)
inputView
è la vista usata per la tastiera, è la stessa di vista
proprietàdismissKeyboard
il metodo può essere chiamato per chiudere la tastieraadvanceToNextInputMode
è usato per cambiare tra le tastieretextDocumentProxy
è l'oggetto che utilizzerai per interagire con l'input di testo correnteself.textDocumentProxy.insertText ("Tuts +") // inserisce la stringa "Tuts +" nel punto di inserimento self.textDocumentProxy.deleteBackward () // Elimina il carattere a sinistra del punto di inserimento
UIInputViewController
conforme al UITextInputDelegate
protocollo, notificandoti quando il testo o la selezione del testo cambia attraverso il selectionWillChange
, selectionDidChange
, textWillChange
e textDidChange
eventiCreiamo una tastiera personalizzata per rendere tutto questo un po 'più tangibile. Creeremo una semplice tastiera in grado di gestire input numerici e operazioni semplici. Useremo un file XIB per l'interfaccia utente della tastiera.
Apri Xcode 6, creane uno nuovo Applicazione vista singola e selezionare veloce come il linguaggio di programmazione. Nominalo CalculatorKeyboard.
Aperto Main.storyboard
e trascinare un campo di testo dal Biblioteca degli oggetti. Lo useremo per testare la tastiera in un secondo momento. Centra il campo di testo e aggiungi i vincoli di layout necessari come mostrato di seguito.
Se chiami textField.becomeFirstResponder ()
nel viewDidLoad
la tastiera si aprirà quando avvii l'app.
Seleziona il file di progetto nel Project Navigator e aggiungi un nuovo target facendo clic sul pulsante più in basso.
Selezionare Estensione dell'applicazione a sinistra, scegli il Tastiera personalizzata modello e nominalo Calcolatrice.
Questo creerà un nuovo gruppo chiamato Calcolatrice, contenente due file KeyboardViewController.swift e Info.plist.
Aperto KeyboardViewController.swift. La tastiera modello ha un pulsante, che consente all'utente di passare da una tastiera all'altra. Rimuovere il codice nel viewDidLoad
metodo.
Fare clic con il pulsante destro del mouse Calcolatrice raggruppa e seleziona Nuovo file… . Seleziona il Interfaccia utente sezione a sinistra, scegliere il vista modello e nominalo Calcolatrice. Questo dovrebbe creare un file chiamato Calculator.xib.
Aprire il file XIB e, nel Ispettore degli attributi a destra, impostare la dimensione su Forma libera e la barra di stato a Nessuna.
Nel Ispettore di taglia imposta la larghezza della vista a 320
e l'altezza a 160
.
Trascina un pulsante da Biblioteca degli oggetti alla vista Nel Ispettore degli attributi, imposta il titolo a 1. Nel Ispettore di taglia, imposta la larghezza e l'altezza del pulsante su 30
. Sposta il pulsante nell'angolo in alto a destra della vista finché non si allinea con i margini.
Copia il pulsante facendo clic e trascinando il pulsante mentre premi il tasto Opzione chiave. Posiziona il secondo pulsante sotto il primo.
Seleziona i pulsanti premendo Comando-A e copia i pulsanti. Posiziona i nuovi pulsanti sotto il primo e il secondo pulsante.
Ripeti il processo per creare un'altra colonna di pulsanti finché non avrai quattro colonne di pulsanti.
Quindi, seleziona la colonna a sinistra e crea una copia che si allinea con il bordo sinistro della vista.
Impostare la larghezza dei pulsanti su 140
punti. Sostituisci il pulsante in alto a sinistra con un'etichetta che ha le stesse dimensioni del pulsante. Rinominare i pulsanti come nello screenshot qui sotto.
Dai alla vista un colore di sfondo bluastro e imposta il colore di sfondo per i pulsanti su bianco con un'opacità del 15%. E per l'etichetta del display, rendila nera con un'opacità del 15%. Imposta la dimensione del testo su 18
punti per ogni oggetto dell'interfaccia utente e imposta il colore del testo su bianco. L'interfaccia utente dovrebbe ora assomigliare a questa:
Per prima cosa è necessario creare una proprietà in cui archiviare l'interfaccia utente.
class KeyboardViewController: UIInputViewController var calculatorView: UIView! ...
Crea un metodo chiamato loadInterface
e chiamalo nel viewDidLoad
metodo del KeyboardViewController
.
class KeyboardViewController: UIInputViewController ... override func viewDidLoad () super.viewDidLoad () loadInterface () func loadInterface () // carica il file del penn var calculatorNib = UINib (nibName: "Calculator", bundle: nil) // instantiate la vista calculatorView = calculatorNib.instantiateWithOwner (self, options: nil) [0] come UIView // aggiungi l'interfaccia alla vista principale view.addSubview (calculatorView) // copia il colore di sfondo view.backgroundColor = calculatorView.backgroundColor ...
A questo punto dovresti essere in grado di testare la tua nuova tastiera. Con il CalculatorKeyboard schema selezionato, crea ed esegui l'applicazione sul tuo dispositivo. Questo aggiungerà una nuova tastiera al tuo dispositivo. Tuttavia, prima di poterlo utilizzare, è necessario prima installarlo.
Vai a impostazioni > Generale > Tastiera > tastiere e selezionare Aggiungi nuova tastiera. Lì troverai il Calcolatrice tastiera nell'elenco delle tastiere di terze parti. Seleziona e installa la tastiera. La prossima volta che aprirai la tastiera dovresti essere in grado di vedere la tua nuova tastiera premendo il prossimo tasto della tastiera.
Se utilizzi il simulatore iOS, la tastiera personalizzata potrebbe non funzionare all'interno della tua app. Per vedere la tastiera premi home e apri Spotlight.
Crea una proprietà per il prossimo tasto della tastiera in KeyboardViewController
classe.
class KeyboardViewController: UIInputViewController @IBOutlet var nextKeyboardButton: UIButton! ...
Aperto Calculator.xib , Selezionare Proprietario del file, e nel Identity Inspector cambia la sua classe in KeyboardViewController
.
Fare clic destro sul Tastiera successiva pulsante e collegare una presa di riferimento al Proprietario del file.
Nel loadInterface
metodo, aggiungiamo un'azione al nextKeyboard
pulsante come mostrato di seguito.
class KeyboardViewController: UIInputViewController ... func loadInterface () ... // Questo farà la chiamata al pulsante advanceToNextInputMode () quando viene toccato nextKeyboardButton.addTarget (self, action: "advanceToNextInputMode", forControlEvents: .TouchUpInside)
Creare una proprietà per il display e collegare la presa di riferimento in Interface Builder.
class KeyboardViewController: UIInputViewController @IBOutlet var display: UILabel! ...
Crea un metodo chiamato clearDisplay
e chiamalo nel viewDidLoad
metodo, dopo aver invocato loadInterface
. Il display dovrebbe ora mostrare 0 quando apri la tastiera.
class KeyboardViewController: UIInputViewController ... override func viewDidLoad () super.viewDidLoad () loadInterface () clearDisplay () ... @IBAction func clearDisplay () display.text = "0"
Connetti il C pulsante di ritoccare dentro evento al clearDisplay
metodo in Interface Builder.
È ora di gestire l'input numerico. Quando apri la tastiera mostra 0 sul display. Se tocchi un tasto numerico, dovrebbe sostituire il display con quel numero. Crea una proprietà denominata shouldClearDisplayBeforeInserting
per implementare questo comportamento.
Crea un metodo chiamato didTapNumber
e collegarlo in Interface Builder a tutti i pulsanti numerici per il ritoccare dentro evento. Il metodo usa il titleLabel
del pulsante per determinare quale numero è stato toccato.
class KeyboardViewController: UIInputViewController var shouldClearDisplayBeforeInserting = true ... @IBAction func didTapNumber (numero: UIButton) if shouldClearDisplayBeforeInserting display.text = "" shouldClearDisplayBeforeInserting = false se var numberAsString = number.titleLabel? .text var numberAsNSString = numberAsString come NSString se var oldDisplay = visualizza? .text! display.text = "\ (oldDisplay) \ (numberAsNSString.intValue)" else display.text = "\ (numberAsNSString.intValue)"
Aggiorna il clearDisplay
metodo come mostrato di seguito.
class KeyboardViewController: UIInputViewController ... @IBAction func clearDisplay () display.text = "0" shouldClearDisplayBeforeInserting = true
Il codice della tastiera ha un target diverso rispetto alla tua app. Per questo motivo i registri di debug non sono visibili. Per vedere i log per il Calcolatrice destinazione, aprire il registro di sistema da iOS Simulator.
Il pulsante per inserire un punto dovrebbe aggiungere un punto al display, ma solo se non è ancora presente un punto.
class KeyboardViewController: UIInputViewController ... @IBAction func didTapDot () if let input = display? .text var hasDot = false per ch in input.unicodeScalars if ch == "." hasDot = true break se hasDot == false display.text = "\ (input)."
Il pulsante per inserire il testo dovrebbe aggiungere il testo di visualizzazione della calcolatrice al punto di inserimento. Per fare questo, usiamo il textDocumentProxy
proprietà come mostrato di seguito.
class KeyboardViewController: UIInputViewController ... @IBAction func didTapInsert () var proxy = textDocumentProxy come UITextDocumentProxy se let input = display? .text as String? proxy.insertText (input)
Perché stiamo implementando una semplice tastiera che non supporta gli alberi di espressione, 1 + 2 * 3
sarà uguale 9
. Useremo un modello più semplice in cui la calcolatrice ha uno slot di memoria interno su cui può applicare le operazioni.
Prendiamo un semplice input per capire come funziona l'algoritmo della calcolatrice:
1
, il display dovrebbe cambiare da 0
a 1
+
, la calcolatrice dovrebbe ricordare di aggiungere il numero successivo immesso a 1
2
, il display dovrebbe cambiare da 1
a 2
*
, il display e la memoria interna della calcolatrice dovrebbero cambiare a 3
, la calcolatrice dovrebbe ricordare di moltiplicare la memoria interna con il numero immesso successivo3
, il display dovrebbe rimanere 3
=
, la calcolatrice dovrebbe applicare l'ultima operazione e il display dovrebbe cambiare 9
osservazioni:
Per implementare la calcolatrice, avremo bisogno di:
memoria interna
proprietà che memorizza il risultato temporaneonextOperation
nextOperation
dopo aver premuto un'operazioneenum Operazione caso Caso di aggiunta Caso di moltiplicazione Caso di sottotazione Caso di divisione Nessuno classe KeyboardViewController: UIInputViewController var internalMemory = 0.0 var nextOperation = Operation.None var shouldCompute = false ...
Crea un metodo chiamato didTapOperation
e collegarlo ai pulsanti operativi ritoccare dentro evento in Interface Builder. Il metodo utilizzerà il titolo del pulsante per determinare quale operazione è stata premuta.
class KeyboardViewController: UIInputViewController ... @IBAction func didTapOperation (operazione: UIButton) if shouldCompute computeLastOperation () se var op = operation.titleLabel? .text switch op case "+": nextOperation = Operation.Addition case "- ": nextOperation = Operation.Subtraction case" X ": nextOperation = Operation.Multiplication case"% ": nextOperation = Operation.Division default: nextOperation = Operation.None
Creare e implementare il computeLastOperation
metodo.
class KeyboardViewController: UIInputViewController ... @IBAction func computeLastOperation () // ricorda di non calcolare se un'altra operazione viene premuta senza inserire prima un altro numero shouldCompute = false se var input = display? .text var inputAsDouble = (input come NSString). doubleValue var result = 0.0 // applica l'operazione switch nextOperation case .Addition: result = internalMemory + inputAsDouble case .Subtraction: result = internalMemory - inputAsDouble case .Multiplication: result = internalMemory * inputAsDouble case .Division: result = internalMemory / inputAsDouble default : result = 0.0 nextOperation = Operation.None var output = "\ (result)" // se il risultato è un numero intero non mostra il punto decimale se output.hasSuffix (". 0") output = "\ ( Int (risultato)) " // truncando alle ultime cinque cifre var components = output.componentsSeparatedByString (". ") If components.count> = 2 var beforePoint = components [0] var afterPoint = components [1] se afterPoint. lengthOfBytes UsingEncoding (NSUTF8StringEncoding)> 5 let index: String.Index = advance (afterPoint.startIndex, 5) afterPoint = afterPoint.substringToIndex (index) output = beforePoint + "." + afterPoint // aggiorna il display display.text = output // salva il risultato internalMemory = result // ricorda di cancellare il display prima di inserire un nuovo numero shouldClearDisplayBeforeInserting = true
Aggiorna il clearDisplayMethod
come mostrato di seguito. Quando l'utente inizia a scrivere il primo numero, la memoria interna deve essere impostata su 0
e nextOperation
dovrebbe essere aggiunta In questo modo, dopo che l'utente ha inserito il primo numero e premuto un'operazione, la calcolatrice ricorderà il numero immesso.
class KeyboardViewController: UIInputViewController ... @IBAction func clearDisplay () display.text = "0" internalMemory = 0 nextOperation = Operation.Addition shouldClearDisplayBeforeInserting = true
Usiamo il IBInspectable attributo di dichiarazione per aggiungere un raggio dell'angolo ai pulsanti e al display. Innanzitutto, crea una sottoclasse di UIButton
e UILabel
.
class RoundButton: UIButton @IBInspectable var cornerRadius: CGFloat = 0 didSet layer.cornerRadius = cornerRadius classe RoundLabel: UILabel @IBInspectable var cornerRadius: CGFloat = 0 didSet layer.cornerRadius = cornerRadius
In Interface Builder, seleziona i pulsanti e cambia la loro classe in RoundButton
nel Identity Inspector. Nel Ispettore degli attributi, dovresti vedere il nuovo attributo del raggio d'angolo.
Fai lo stesso per l'etichetta del display. La tua tastiera dovrebbe ora apparire così.
Ora dovresti essere in grado di creare una tastiera personalizzata in iOS utilizzando le API di estensione dell'app. Ricorda che ogni tastiera personalizzata deve avere un modo per passare alla tastiera successiva e che la tastiera non può connettersi a Internet, accedere ai servizi di localizzazione o parlare con la sua app contenente di default, ma puoi richiedere queste funzionalità.
Il sistema utilizzerà la tastiera predefinita per i campi protetti, come i campi della password e del numero di telefono. Non dimenticare che il codice per la tastiera personalizzata vive in un target separato. Per questo motivo i registri di debug non sono visibili. Per vederli, apri il registro di sistema da iOS Simulator.