Помощник представления действия на пехлеви - работает вокруг?

В других ответах нет ничего плохого, это просто другой подход с преимуществом большей сосредоточенности на ООП - 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)
    }

    ....
}
10
задан gnarf 2 June 2009 в 18:44
поделиться

4 ответа

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

Помощник представления действий страдает не только от проблем с производительностью, но также создает ужасные кошмары отладки, и если вам это нужно, то ваше приложение, вероятно, не следует за MVC, и, следовательно, вы используете контроллер для повторного использования вместо модели, которая является целью шаблона.

Вы можете визуализировать частичные данные из вашего макета или текущего действия с помощью методов рендеринга или частичных объектов представления.

7
ответ дан 4 December 2019 в 01:57
поделиться

Если вы не генерируете панели вкладок / вкладок из существующей разметки и загружаете контент по запросу, вам просто необходимо проверить, есть ли у пользователя разрешение на доступ к вкладке, прежде чем отображение самой вкладки и снова при попытке загрузить содержимое вкладки.

Проверка того, имеет ли пользователь эти разрешения доступа, должна быть приемлемым режимом работы и не должна быть дорогостоящей.

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

1
ответ дан 4 December 2019 в 01:57
поделиться

Я не совсем уверен, в чем именно заключается ваша проблема, однако вы можете отключить макет:

$this->_helper->layout->disableLayout();

Тогда запрошенное действие просто отобразит его сценарий просмотра, который вы можете загрузить во вкладку .

Любой код авторизации, который у вас есть, будет работать как обычно, и вы можете отобразить запрошенный сценарий просмотра для действия или нет, в зависимости от того, есть ли у них доступ.

1
ответ дан 4 December 2019 в 01:57
поделиться

Вы можете перехватить любые исключения доступа с помощью блока try / catch:

try { // action throwing exceptions } catch (Exception $e) { // catch silently }
0
ответ дан 4 December 2019 в 01:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: