2014-10-28 10 views
5

Ich habe Stunden damit verbracht, herauszufinden, wie man erstellen/dann eine benutzerdefinierte inputView zu arbeiten bekommen. Ich habe ein Raster von TextInputs (denke Scrabble-Board), die, wenn gedrückt, sollte eine benutzerdefinierte inputView laden, um Text einzufügen.Benutzerdefinierte Eingabe Ansicht in Swift

Ich habe eine .xib Datei mit dem UI elements für die benutzerdefinierte inputView erstellt. Ich war in der Lage, eine CustomInputViewController zu erstellen und die inputView erscheinen, aber nie in der Lage, die tatsächliche TextInput zu erhalten, um es zu aktualisieren Wert/Text.

Die Apple-Dokumentation hat Licht in die Arbeit gebracht und die vielen Tutorials, die ich gesehen habe, benutzen Obj-C (das ich wegen kleiner Dinge, die jetzt nicht mehr möglich sind, nicht umwandeln konnte) in schnell gemacht).

Was ist die übergreifende Architektur und die notwendigen Codeelemente, die implementiert werden sollten, um ein customInputView für mehrere textInputs (Delegate Kette, Controller, .xibs, Ansichten usw.) zu erstellen?

+0

Erstellen Sie eine benutzerdefinierte Klassendatei und legen Sie diese als die Klasse für Ihre Xib in InterfaceBuilder. Dann können Sie mit Strg-Ziehen von UI-Elementen in Ihre Klassendatei (Assistent-Editor) um IBOutlets zu erstellen. Verwenden Sie diese Steckplätze in Ihrem Code, um die UI-Elemente zu aktualisieren. – zisoft

+0

Ich konnte IBOutlets/IBActions für die Schaltflächen in der benutzerdefinierten Ansicht erstellen. Dies war notwendig, aber nicht ausreichend, um Schaltflächen in der customView zu erhalten, um textInput/keyboardFunctionality mit der Ansicht von TextInputs zu kommunizieren. – codycoats

+0

Müssen Ihre Ansichten nicht das richtige Protokoll implementieren/einhalten? (UITextInput?). Möglicherweise müssen Sie ihnen auch sagen, dass sie Ersthelfer werden, wenn sie angezapft werden. Ich würde versuchen, Unterklasse UIControl vs UIView – nielsbot

Antwort

7

Sie sollten nicht durch all diesen Ärger gehen. Es gibt eine neue Klasse in iOS 8 mit dem Namen: UIAlertController, in der Sie TextFields hinzufügen können, damit der Benutzer Daten eingeben kann. Sie können es als Alert oder ActionSheet formatieren.

Beispiel:

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

Nachdem Sie nun den Controller haben, fügen Sie Felder hinzu:

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 

hinzufügen Aktionstasten:

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

Präsens der Controller, wann immer Sie wollen mit :

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

Wie Sie sehen, haben Sie verschiedene Handler, um bei jedem Schritt benutzerdefinierten Code zu übergeben.

Als Beispiel, das ist, wie es aussehen würde: An example of how it could look

9

eine Nib-Datei mit dem entsprechenden inputView Layout und Elementen einrichten. In meinem Fall setze ich jede Taste auf eine Aktion auf Dateibesitzer von inputViewButtonPressed.

Richten Sie ein Storyboard (oder eine Schreibfeder, falls Sie dies bevorzugen) für einen View-Controller ein.

dann den folgenden Code verwenden, sollten Sie bekommen, was Sie suchen:

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() 
    } 
} 

Alternativ, wenn Sie wollen mehr Tastatur artig sein, können Sie diese Funktion als Aktion verwenden (es nutzt die neue let Syntax von Swift 1.2), es brechen, wenn Sie 1.1-Kompatibilität benötigen:

@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) 
     } 
    } 

Dies verwendet das UITextInput Protokoll das Textfeld entsprechend zu aktualisieren.Löschen ist ein wenig komplizierter, aber immer noch nicht zu schlecht:

@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

Vielen Dank für diese Antwort, David. Wenn ich die Tastatur an einigen Stellen wiederverwenden möchte, was würden Sie als den besten Weg empfehlen, dies zu tun? –

+0

Sie könnten 'UIViewController' von der Unterklasse ableiten, oder Sie könnten diesen Code entweder in einer 'UITextField' -Unterklasse oder einer separaten Controller-Klasse instanziieren. –