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