NSPredicateEditorRowTemplate, указание пути к ключу с пробелами?

#objective-c #cocoa #nspredicateeditor

#objective-c #cocoa #nspredicateeditor

Вопрос:

Согласно предыдущему вопросу, я неохотно отказался от использования IB / Xcode4 для редактирования NSPredicateEditor и сделал это чисто в коде.

При редактировании полей с помощью графического интерфейса пути к ключу могут быть указаны с пробелами, например ‘field name’, и это заставляет их работать как пути к ключу в стиле ‘fieldName’, при этом они по-прежнему отображаются в пользовательском интерфейсе с пробелами. Как мне сделать это в коде? Когда я указываю их с пробелами, они не работают. Когда я указываю их в camelCase, они работают, но отображаются в camelCase. Я просто добавляю кучу NS-выражений, подобных этому:

 [NSExpression expressionForKeyPath:@"original filename"]
  

Ответ №1:

Правильный способ получить читаемые человеком строки в представлениях строк редактора предикатов — использовать возможности локализации NSRuleEditor и NSPredicateEditor .

Если вы будете следовать инструкциям в этом сообщении в блоге, у вас будет все необходимое для локализации редактора.

В качестве примера, допустим, ваш путь к ключу fileName , вы поддерживаете 2 оператора ( is и contains ), и вы хотите, чтобы пользователь ввел строку. В итоге вы получите файл strings, который выглядит следующим образом:

 "%[fileName]@ %[is]@ %@" = "%1$[fileName]@ %2$[is]@ %3$@";
"%[fileName]@ %[contains]@ %@" = "%1$[fileName]@ %2$[contains]@ %3$@";
  

Вы можете использовать этот файл для размещения материалов, удобочитаемых человеком, и даже изменить порядок вещей:

 "%[fileName]@ %[is]@ %@" = "%1$[original filename]@ %2$[is]@ %3$@";
"%[fileName]@ %[contains]@ %@" = "%3$@ %2$[is contained in]@ %1$[original filename]@";
  

Как только вы локализовали файл strings, вы передаете этот файл обратно в редактор предикатов, и он извлекает переведенные значения, творит свое волшебство, и все отображается правильно.

Ответ №2:

Если вы не хотите локализовать все, просто сопоставьте пути к ключам, рассмотрите возможность переопределения value(forKey:) в вашем оцениваемом объекте следующим образом:

 class Match: NSObject {

    var date: Date?
    var fileName: String?

    override func value(forKey key: String) -> Any? {
        // Alternatively use static dictionary for mapping key paths
        super.value(forKey: camelCasedKeyPath(forKey: key))
    }

    private func camelCasedKeyPath(forKey key: String) -> String {
        key.components(separatedBy: .whitespaces)
            .enumerated()
            .map { $0.offset > 0 ? $0.element.capitalized : $0.element.lowercased() }
            .joined()
    }
}