Пользовательский вид ввода в Swift

Я потратил часы, пытаясь выяснить, как создать / затем получить кастом inputView работать. У меня есть сетка TextInputs (думаю, скрабблборд) что при нажатии должен загружаться кастом inputView вставить текст.

Я создал файл .xib, содержащий UI elements для обычая inputView, Я смог создать CustomInputViewController и иметь inputView появляются, но никогда не могут получить фактическое TextInput обновить его значение / текст.

Документация Apple показала, как заставить это работать, и многие учебники, которые я видел, использовали Obj-C (который я не смог преобразовать из-за мелких вещей, которые сейчас не могут быть выполнены быстро),

Что такое всеобъемлющая архитектура и необходимые фрагменты кода, которые должны быть реализованы для создания customInputView для нескольких textInputs (цепочка делегатов, контроллер,.xibs, представления и т. д.)?

2 ответа

Решение

Вы не должны проходить через все эти хлопоты. В iOS 8 появился новый класс: UIAlertController где вы можете добавить TextFields для пользователя для ввода данных. Вы можете оформить его как Alert или ActionSheet.

Пример:

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

Теперь, когда у вас есть контроллер, добавьте в него поля:

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

Добавить кнопки действий:

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

Представьте контроллер, когда вы хотите с:

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

Как видите, у вас есть различные обработчики для передачи пользовательского кода на любом этапе.

Например, вот как это будет выглядеть:Пример того, как это может выглядеть

Настройте nib-файл с соответствующим макетом inputView и элементами. В моем случае я установил для каждой кнопки действие с владельцем файла inputViewButtonPressed,

Настройте раскадровку (или перо, если хотите) для контроллера представления.

Затем, используя следующий код, вы получите то, что ищете:

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

В качестве альтернативы, если вы хотите быть более похожим на клавиатуру, вы можете использовать эту функцию в качестве своего действия (она использует новый синтаксис let из Swift 1.2), разбейте ее, если вам нужна совместимость 1.1:

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

Это использует UITextInput протокол для обновления текстового поля по мере необходимости. Обработка удаления немного сложнее, но все же не так уж плохо:

    @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: "")
            }
        }
    }
Другие вопросы по тегам