macOS 10.12 и новее
Начиная с macOS 10.12 (Sierra), есть три новых NSTextField
конструктора:
NSTextField(labelWithString:)
, что в комментарии к заголовочному файлу гласит: «Создает неразворачиваемое, не редактируемое, не выбираемое текстовое поле, которое отображает текст системным шрифтом по умолчанию».
NSTextField(wrappingLabelWithString:)
, который в комментарии к заголовочному файлу гласит: «Создает переносимое, не редактируемое, выбираемое текстовое поле, отображающее текст системным шрифтом по умолчанию».
NSTextField(labelWithAttributedString:)
, что в комментарии к заголовочному файлу гласит «Создает не редактируемое, не выбираемое текстовое поле, в котором отображается атрибутивный текст. Режим разрыва строки в этом поле определяется атрибутом NSParagraphStyle приписанной строки. ”
Я протестировал те, которые берут простую (не приписываемую строку), и они создают текстовые поля, которые похожи, но не точно совпадают с текстовыми полями, созданными в раскадровке или XIB.
Важным отличием является то, что оба конструктора создают текстовое поле с textBackgroundColor
(обычно чисто белым) в качестве цвета фона, тогда как в текстовом поле раскадровки используется controlColor
(обычно около 90% белого).
Неважно, что оба конструктора также устанавливают свои шрифты, вызывая NSFont.systemFont(ofSize: 0)
(который создает объект NSFont
, отличный от моего кода ниже, но они обертывают тот же основной шрифт Core Text).
Конструктор wrappingLabelWithString:
устанавливает isSelectable
поля в true
. (Это задокументировано в заголовочном файле.)
macOS 10.11 и ранее
Я сравнил четыре NSTextField
экземпляра: один, созданный перетаскиванием «Метка» на раскадровку, другой созданный перетаскиванием «Оберточной метки» на раскадровку, и два в коде. Затем я тщательно изменил свойства меток, созданных в коде, чтобы все их свойства были точно такими же, как метки, созданные в раскадровке. Эти два метода являются результатом:
extension NSTextField {
/// Return an `NSTextField` configured exactly like one created by dragging a “Label” into a storyboard.
class func newLabel() -> NSTextField {
let label = NSTextField()
label.isEditable = false
label.isSelectable = false
label.textColor = .labelColor
label.backgroundColor = .controlColor
label.drawsBackground = false
label.isBezeled = false
label.alignment = .natural
label.font = NSFont.systemFont(ofSize: NSFont.systemFontSize(for: label.controlSize))
label.lineBreakMode = .byClipping
label.cell?.isScrollable = true
label.cell?.wraps = false
return label
}
/// Return an `NSTextField` configured exactly like one created by dragging a “Wrapping Label” into a storyboard.
class func newWrappingLabel() -> NSTextField {
let label = newLabel()
label.lineBreakMode = .byWordWrapping
label.cell?.isScrollable = false
label.cell?.wraps = true
return label
}
}
Если вы используете один из этих методов, не забудьте установить фрейм поля или отключить translatesAutoresizingMaskIntoConstraints
и добавить ограничения.
Вот код, который я использовал для сравнения различных текстовых полей, если вы хотите проверить:
import Cocoa
class ViewController: NSViewController {
@IBOutlet var label: NSTextField!
@IBOutlet var multilineLabel: NSTextField!
override func loadView() {
super.loadView()
}
override func viewDidLoad() {
super.viewDidLoad()
let codeLabel = NSTextField.newLabel()
let codeMultilineLabel = NSTextField.newWrappingLabel()
let labels = [label!, codeLabel, multilineLabel!, codeMultilineLabel]
for keyPath in [
"editable",
"selectable",
"allowsEditingTextAttributes",
"importsGraphics",
"textColor",
"preferredMaxLayoutWidth",
"backgroundColor",
"drawsBackground",
"bezeled",
"bezelStyle",
"bordered",
"enabled",
"alignment",
"font",
"lineBreakMode",
"usesSingleLineMode",
"formatter",
"baseWritingDirection",
"allowsExpansionToolTips",
"controlSize",
"highlighted",
"continuous",
"cell.opaque",
"cell.controlTint",
"cell.backgroundStyle",
"cell.interiorBackgroundStyle",
"cell.scrollable",
"cell.truncatesLastVisibleLine",
"cell.wraps",
"cell.userInterfaceLayoutDirection"
] {
Swift.print(keyPath + " " + labels.map({ ($0.value(forKeyPath: keyPath) as? NSObject)?.description ?? "nil" }).joined(separator: " "))
}
}
}