Использование & ldquo; Next & rdquo; как ключ возврата

Это 2017, и возможно настроить таргетинг на определенные варианты выбора. В моем проекте у меня есть таблица с классом = «варианты», а опции выбора находятся в ячейке таблицы td = «значение», а в элементе выбора есть идентификатор # pa_color. Элемент option также имеет параметр class = "attach" (среди других тегов класса). Если пользователь вошел в систему как оптовый клиент, они могут видеть все параметры цвета. Но розничным клиентам не разрешено приобретать 2 цветовых варианта, поэтому я отключил их

<option class="attached" disabled>color 1</option>
<option class="attached" disabled>color 2</option>

. Для этого потребовалась небольшая логика, но вот как я нацелился на отключенные опции выбора.

CSS

table.variations td.value select#pa_color option.attached:disabled {
display: none !important;
}

При этом мои параметры цвета видны только для оптовых покупателей.

29
задан nhgrif 20 November 2014 в 01:21
поделиться

4 ответа

Убедитесь, что в ваших текстовых полях установлен делегат, и реализуйте метод textFieldShouldReturn. Этот метод вызывается, когда пользователь нажимает клавишу возврата (независимо от того, как он выглядит).

Метод может выглядеть примерно так:

func textFieldShouldReturn(textField: UITextField) -> Bool {
    if textField == self.field1 {
        self.field2.becomeFirstResponder()
    }

    return true
}

Фактическая логика здесь может отличаться. Существует множество подходов, и я бы определенно рекомендовал не использовать массивную цепочку if / else, если у вас много текстовых полей, но суть здесь в том, чтобы определить, какое представление активно в данный момент, чтобы определить, каким должно быть представление. активный. Как только вы определили, какое представление должно стать активным, вызовите метод этого представления becomeFirstResponder.


Для некоторой чистоты кода вы можете рассмотреть расширение UITextField, которое выглядит примерно так:

private var kAssociationKeyNextField: UInt8 = 0

extension UITextField {
    var nextField: UITextField? {
        get {
            return objc_getAssociatedObject(self, &kAssociationKeyNextField) as? UITextField
        }
        set(newField) {
            objc_setAssociatedObject(self, &kAssociationKeyNextField, newField, .OBJC_ASSOCIATION_RETAIN)
        }
    }
}

А затем измените наш метод textFieldShouldReturn, чтобы он выглядел так:

func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.nextField?.becomeFirstResponder()
    return true
}

Как только вы это сделаете, нужно просто установить новое свойство nextField каждого текстового поля в viewDidLoad:

self.field1.nextField = self.field2
self.field2.nextField = self.field3
self.field3.nextField = self.field4
self.field4.nextField = self.field1

Хотя, если мы действительно Если бы мы хотели, мы могли бы добавить префикс к свойству @IBOutlet, и это позволило бы нам подключить наше свойство "nextField" прямо в конструкторе интерфейса.

Измените расширение так, чтобы оно выглядело следующим образом:

private var kAssociationKeyNextField: UInt8 = 0

extension UITextField {
    @IBOutlet var nextField: UITextField? {
        get {
            return objc_getAssociatedObject(self, &kAssociationKeyNextField) as? UITextField
        }
        set(newField) {
            objc_setAssociatedObject(self, &kAssociationKeyNextField, newField, .OBJC_ASSOCIATION_RETAIN)
        }
    }
}

А теперь подключите свойство nextField в конструкторе интерфейсов:

enter image description here

] (Настройте своего делегата, пока вы здесь тоже.)


И, конечно, если свойство nextField возвращает nil, клавиатура просто скрывается.

83
ответ дан nhgrif 20 November 2014 в 01:21
поделиться

Вот пример в Swift:

Я создал экран с 6 UITextField с. Я назначил им теги с 1 по 6 в Интерфейсном Разработчике. Я также изменил ключ возврата на следующий в IB. Затем я реализовал следующее:

import UIKit

// Make your ViewController a UITextFieldDelegate    
class ViewController: UIViewController, UITextFieldDelegate {

    // Use a dictionary to define text field order 1 goes to 2, 2 goes to 3, etc.
    let nextField = [1:2, 2:3, 3:4, 4:5, 5:6, 6:1]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // Make ourselves the delegate of the text fields so that textFieldShouldReturn
        // will be called when the user hits the Next/Return key
        for i in 1...6 {
            if let textField = self.view.viewWithTag(i) as? UITextField {
                textField.delegate = self
            }
        }
    }

    // This is called when the user hits the Next/Return key        
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        // Consult our dictionary to find the next field
        if let nextTag = nextField[textField.tag] {
            if let nextResponder = textField.superview?.viewWithTag(nextTag) {
                // Have the next field become the first responder
                nextResponder.becomeFirstResponder()
            }
        }
        // Return false here to avoid Next/Return key doing anything
        return false
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
8
ответ дан vacawama 20 November 2014 в 01:21
поделиться

В других ответах нет ничего плохого, это просто другой подход с преимуществом большей сосредоточенности на ООП - imho (хотя это немного сложнее, его можно использовать повторно). В раскадровке я начинаю добавлять теги с определенным диапазоном (например, 800-810), которые определяют конкретный порядок полей, между которыми я хочу перемещаться. Это дает преимущество работы со всеми подпредставлениями в главном представлении, так что можно перемещаться между UITextField и UITextView (и любым другим элементом управления) по мере необходимости.

Обычно - обычно я пытаюсь получить сообщение контроллеров представления между представлениями и объектами пользовательских обработчиков событий. Поэтому я использую сообщение (также известное как NSNotification), переданное обратно в контроллер представления из пользовательского класса делегата.

(Обработчик делегата TextField)

Примечание. В AppDelegate.swift: let defaultCenter = NSNotificationCenter.defaultCenter ()

//Globally scoped
struct MNGTextFieldEvents {
    static let NextButtonTappedForTextField = "MNGTextFieldHandler.NextButtonTappedForTextField"
}

class MNGTextFieldHandler: NSObject, UITextFieldDelegate {

    var fields:[UITextField]? = []

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        return true
    }
    func textFieldDidBeginEditing(textField: UITextField) {
        textField.backgroundColor = UIColor.yellowColor()
    }
    func textFieldDidEndEditing(textField: UITextField) {
        textField.backgroundColor = UIColor.whiteColor()
    }
    func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
        return true
    }
    func textFieldShouldClear(textField: UITextField) -> Bool {
        return false
    }
    func textFieldShouldEndEditing(textField: UITextField) -> Bool {
        return true
    }
    func textFieldShouldReturn(textField: UITextField) -> Bool {

        //passes the message and the textField (with tag) calling the method
        defaultCenter.postNotification(NSNotification(name: MNGTextFieldEvents.NextButtonTappedForTextField, object: textField))

        return false
    }
}

Это позволяет моему контроллеру представления сосредоточиться на своей основной работе по обработке сообщений между объектами, моделью и видом.

(View Controller получает сообщение от делегата и передает инструкции, используя функцию advanceToNextField)

Примечание. В моей раскадровке мои классы пользовательских обработчиков определены с использованием NSObject, и этот объект связан с Раскадровка в качестве делегата для элементов управления, которые мне нужно контролировать. Что приводит к автоматической инициализации пользовательского класса обработчика.

class MyViewController: UIViewController {
    @IBOutlet weak var tagsField: UITextField! { didSet {
        (tagsField.delegate as? MNGTextFieldHandler)!.fields?.append(tagsField)
        }
    }
    @IBOutlet weak var titleField: UITextField!{ didSet {
        (titleField.delegate as? MNGTextFieldHandler)!.fields?.append(titleField)
        }
    }
    @IBOutlet weak var textView: UITextView! { didSet {
     (textView.delegate as? MNGTextViewHandler)!.fields?.append(textView)

        }
    }

    private struct Constants {
     static let SelectorAdvanceToNextField = Selector("advanceToNextField:")
}
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        registerEventObservers()
    }
    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
        deRegisterEventObservers()
    }

    func advanceToNextField(notification:NSNotification) {
        let currentTag = (notification.object as! UIView).tag

        for aView in self.view.subviews {
            if aView.tag == currentTag + 1 {
                aView.becomeFirstResponder()
            }
        }
    }

    func registerEventObservers () {

        defaultCenter.addObserver(self, selector: Constants.SelectorAdvanceToNextField, name: MNGTextFieldEvents.NextButtonTappedForTextField, object: nil)
    }

    func deRegisterEventObservers() {

        defaultCenter.removeObserver(self, name: MNGTextFieldEvents.NextButtonTappedForTextField, object: nil)
    }

    ....
}
2
ответ дан Tommie C. 20 November 2014 в 01:21
поделиться

Просто еще один способ добиться результата, который я нашел полезным. У моего приложения было 11 текстовых полей, за которыми следовал текстовый просмотр. Мне нужно было иметь возможность циклически проходить по всем полям, используя следующую клавишу, а затем подать в отставку клавиатуру, следуя текстовому обзору (то есть другим примечаниям).

В раскадровке я установил тэг на все поля (и текст, и текстовое представление), начиная с 1 по 12, 12 - это текстовое представление.

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

В коде я написал следующее:

func textFieldShouldReturn(textField: UITextField) -> Bool {

    let nextTag = textField.tag + 1

    //Handle Textview transition, Textfield programmatically
    if textField.tag == 11 {
        //Current tag is 11, next field is a textview
        self.OtherNotes.becomeFirstResponder()

    } else if nextTag > 11 {
        //12 is the end, close keyboard
        textField.resignFirstResponder()

    } else {
        //Between 1 and 11 cycle through using next button
        let nextResponder = self.view.viewWithTag(nextTag) as? UITextField
        nextResponder?.becomeFirstResponder()

    }

    return false
}

func textFieldDidEndEditing(textField: UITextField) {

    textField.resignFirstResponder()
}

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {

    //Remove keyboard when clicking Done on keyboard
    if(text == "\n") {
        textView.resignFirstResponder()
        return false
    }
    return true
}
1
ответ дан sarac 20 November 2014 в 01:21
поделиться