2014-10-28 12 views
5

Ho passato ore a cercare di capire come creare/quindi ottenere un inputView personalizzato per funzionare. Ho una griglia di TextInputs (si pensi alla scheda scrabble) che quando viene premuto dovrebbe caricare un numero personalizzato inputView per inserire del testo.Visualizzazione inserimento personalizzato in Swift

ho creato un file di .xib contenente la UI elements per il costume inputView. Sono stato in grado di creare un CustomInputViewController e di visualizzare inputView ma mai in grado di ottenere l'effettivo TextInput per aggiornare il valore /testo.

La documentazione di Apple è sembrata leggera su come farlo funzionare e le numerose esercitazioni che ho visto hanno utilizzato Obj-C (che non sono riuscito a convertire a causa di piccole cose che sembrano non poter essere ora fatto in fretta).

Qual è l'architettura generale e le parti di codice necessarie che devono essere implementate per creare un customInputView per più textInputs (catena delegata, controller, .xibs, viste ecc.)?

+0

Creare un file di classe personalizzato e impostarlo come classe per il tuo xib in InterfaceBuilder. Quindi è possibile trascinare ctrl dagli elementi dell'interfaccia utente al file di classe (editor di assistente) per creare IBOutlets. Usa queste uscite nel tuo codice per aggiornare gli elementi dell'interfaccia utente. – zisoft

+0

Sono stato in grado di creare IBOutlets/IBActions per i pulsanti in customView. Questo è stato necessario ma non sufficiente per ottenere pulsanti in customView per comunicare textInput/keyboardFunctionality alla vista di TextInputs. – codycoats

+0

le tue opinioni non devono implementare/conformarsi al protocollo corretto? (UITextInput?). potresti anche dover dire loro di diventare il primo soccorritore quando vengono toccati. Proverei la sottoclasse di UIControl contro UIView – nielsbot

risposta

7

Non si dovrebbe passare attraverso tutti quei fastidi. C'è una nuova classe in iOS 8 chiamata: UIAlertController dove puoi aggiungere campi di testo per l'utente per inserire dati. Puoi formattarlo come avviso o foglio di lavoro.

Esempio:

let alertAnswer = UIAlertController(title: "Input your scrabble Answer", message: nil, preferredStyle: .Alert) // or .ActionSheet 

Ora che avete il controller, aggiungere campi ad esso:

alertAnswer.addTextFieldWithConfigurationHandler { (get) -> Void in 
      getAnswer.placeholder = "Answer" 
      getAnswer.keyboardType = .Default 
      getAnswer.clearsOnBeginEditing = true 
      getAnswer.borderStyle = .RoundedRect 
     } // add as many fields as you want with custom tweaks 

Aggiungi pulsanti di azione:

let submitAnswer = UIAlertAction(title: "Submit", style: .Default, handler: nil) 
let cancel = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil) 
alertAnswer.addAction(submitAnswer) 
alertAnswer.addAction(cancel) 

Presente il controller ogni volta che desiderate con :

self.presentViewController(alertAnswer, animated: true, completion: nil) 

Come vedete, avete vari gestori per passare codice personalizzato in qualsiasi momento.

A titolo di esempio, questo è come dovrebbe apparire: An example of how it could look

9

impostare un file di pennino con il layout inputView appropriato e articoli. Nel mio caso, ho impostato ciascun pulsante su un'azione su File Owner of inputViewButtonPressed.

Impostare uno storyboard (o un pennino se si preferisce) per un controller di visualizzazione.

Poi utilizzando il seguente codice, si dovrebbe ottenere quello che stai cercando:

class ViewController: UIViewController, UITextFieldDelegate { 
    var myInputView : UIView! 
    var activeTextField : UITextField? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // load input view from nib 
     if let objects = NSBundle.mainBundle().loadNibNamed("InputView", owner: self, options: nil) { 
      myInputView = objects[0] as UIView 
     } 

     // Set up all the text fields with us as the delegate and 
     // using our input view 
     for view in self.view.subviews { 
      if let textField = view as? UITextField { 
       textField.inputView = myInputView 
       textField.delegate = self 
      } 
     } 
    } 

    func textFieldDidBeginEditing(textField: UITextField) { 
     activeTextField = textField 
    } 

    func textFieldDidEndEditing(textField: UITextField) { 
     activeTextField = nil 
    } 

    @IBAction func inputViewButtonPressed(button:UIButton) { 
     // Update the text field with the text from the button pressed 
     activeTextField?.text = button.titleLabel?.text 

     // Close the text field 
     activeTextField?.resignFirstResponder() 
    } 
} 

In alternativa, se hai intenzione di essere più tastiera-like, è possibile utilizzare questa funzione come la vostra azione (utilizza la nuova sintassi let da Swift 1.2), disgregare se avete bisogno di 1.1 compatibilità:

@IBAction func insertButtonText(button:UIButton) { 
     if let textField = activeTextField, title = button.titleLabel?.text, range = textField.selectedTextRange { 
      // Update the text field with the text from the button pressed 
      textField.replaceRange(range, withText: title) 
     } 
    } 

Questo utilizza il protocollo UITextInput per aggiornare il campo di testo a seconda dei casi.La gestione dell'eliminazione è un po 'più complicata, ma non ancora male:

@IBAction func deleteText(button:UIButton) { 
     if let textField = activeTextField, range = textField.selectedTextRange { 
      if range.empty { 
       // If the selection is empty, delete the character behind the cursor 
       let start = textField.positionFromPosition(range.start, inDirection: .Left, offset: 1) 
       let deleteRange = textField.textRangeFromPosition(start, toPosition: range.end) 
       textField.replaceRange(deleteRange, withText: "") 
      } 
      else { 
       // If the selection isn't empty, delete the chars in the selection 
       textField.replaceRange(range, withText: "") 
      } 
     } 
    } 
+0

Grazie mille per questa risposta, David. Se volessi riutilizzare la tastiera in alcuni punti, quale sarebbe il miglior modo per farlo? –

+0

È possibile creare sottoclasse di 'UIViewController' oppure è possibile creare un'istanza di questo codice in una sottoclasse' UITextField' o in una classe controller separata. –

Problemi correlati