Ответ 1
Лучше всего использовать NSTextView и - (void)setInsertionPointColor:(NSColor *)color
.
Я установил NSTextField
с цветным текстом белого цвета, а цвет фона - как черный (несмотря на то, что цвет фона не отображается, поэтому он прозрачный). Все в интерфейсе Builder.
Проблема, с которой я столкнулась, - , курсор черный, и вряд ли видимый. Не отображается ли курсор цветом текста? Любые идеи, как я могу это исправить?
В противном случае NSTextField
выглядит так, как будто он не может быть отредактирован.
Лучше всего использовать NSTextView и - (void)setInsertionPointColor:(NSColor *)color
.
Так как на практике NSText *, возвращаемый -currentEditor для NSTextField, всегда является NSTextView *, я добавил следующий код в свой собственный подкласс NSTextField:
-(BOOL) becomeFirstResponder
{
BOOL success = [super becomeFirstResponder];
if( success )
{
// Strictly spoken, NSText (which currentEditor returns) doesn't
// implement setInsertionPointColor:, but it an NSTextView in practice.
// But let be paranoid, better show an invisible black-on-black cursor
// than crash.
NSTextView* textField = (NSTextView*) [self currentEditor];
if( [textField respondsToSelector: @selector(setInsertionPointColor:)] )
[textField setInsertionPointColor: [NSColor whiteColor]];
}
return success;
}
Итак, если вы уже заменяете этот класс, потому что вы делаете собственный фоновый рисунок, это может быть более инкапсулированное решение. Возможно, есть даже способ переместить это в NSCell, что было бы более чистым, поскольку NSCell - это тот, кто делает чертеж и знает цвета в любом случае.
NSTextField *textField = self.textField;
NSColor *insertionPointColor = [NSColor blueColor];
NSTextView *fieldEditor = (NSTextView*)[textField.window fieldEditor:YES
forObject:textField];
fieldEditor.insertionPointColor = insertionPointColor;
Предполагая, что вы хотите установить цвет вставки, а не курсор мыши, следует использовать предложение setInsertionPointColor:
.
Тем не менее, вам не обязательно менять значение NSTextField
на NSTextView
. Редактором поля для окна, в котором находится NSTextField
, является NSTextView
. Поэтому, когда ваш NSTextField
становится ключевым видом, вы можете захватить редактор полей и вызвать setInsertionPointColor:
. Вам может понадобиться reset цвет, когда ваше поле перестает быть ключевым видом.
Вы можете получить редактор полей с помощью NSWindow
fieldEditor:forObject:
или NSCell
fieldEditorForView:
.
Если у вас есть подкласс NSTextField, вы можете использовать его подклассом NSTextFieldCell и переопределить -(NSText*)setUpFieldEditorAttributes:(NSText*)textObj
. В этом методе вы можете установить цвет точки вставки один раз, и он останется, пока редактор полей активен для этого текстового поля. Хотя, когда редактор поля перемещается в другое поле редактирования, цвет точки вставки останется, если вы не reset.
Вдохновленный великим ответом Jon Steinmetz Я создал следующий пример.
Я добавил NSSecureTextField
в представление приложения и связал его с IBOutlet
переменной-членом I, помещенной в AppDelegate
.
@implementation AppDelegate
@synthesize password = m_password;
- (void)awakeFromNib {
assert(m_password);
self.password.backgroundColor = [NSColor blackColor];
}
Затем я создал пользовательский класс NSSecureTextField
. Я заметил, что в некоторых случаях недостаточно установить цвета в awakeFromNib
, но я не могу объяснить причину этого.
@implementation CustomSecureTextField
- (void)customize {
// Customize the text and caret color.
NSColor* foregroundColor = [NSColor whiteColor];
self.textColor = foregroundColor;
[[self.cell fieldEditorForView:self] setInsertionPointColor:foregroundColor];
}
- (void)awakeFromNib {
[self customize];
}
- (void)textDidBeginEditing:(NSNotification*)notification {
// Called when the user inputs a character.
[self customize];
}
- (void)textDidEndEditing:(NSNotification*)notification {
// Called when the user clicks into the field for the first time.
[self customize];
}
- (void)textDidChange:(NSNotification*)notification {
// Just in case ... for the paranoid programmer!
[self customize];
}
@end
Примечание.. Хотя я не понимаю, почему фоновый цвет не может быть установлен, когда я делаю это в производном классе, как с textColor
. Это позволило бы избавиться от IBOutlet
и переменной-члена.
Я вызвал insertionPointColor
в viewDidLoad
и приложение вылетает.
Я исправил это, вызвав insertionPointColor
на viewDidAppear
.
Swift разработчикам:
Установите метод inserttionPointColor в расширение:
extension NSTextField {
public func customizeCursorColor(_ cursorColor: NSColor) {
let fieldEditor = self.window?.fieldEditor(true, for: self) as! NSTextView
fieldEditor.insertionPointColor = cursorColor
}
}
и позвоните
override func viewDidAppear() {
super.viewDidAppear()
textField.customizeCursorColor(NSColor.red)
}
Решение Swift 4
override func viewDidAppear() {
super.viewDidAppear()
guard let window = _textField.window, let fieldEditor = window.fieldEditor(true, for: _textField) as? NSTextView else { return }
fieldEditor.insertionPointColor = .white
}
Если вы используете захват селектора времени выполнения Objective C в сочетании с решением для uliwitness, вы можете добиться этого без создания подкласса NSTextField, здесь я использую RxCocoa methodInvoked
в качестве примера:
import Cocoa
import RxCocoa
extension NSTextField {
func withCursorColor(_ color: NSColor) {
rx.methodInvoked(#selector(becomeFirstResponder))
.subscribe(onNext: { [unowned self] _ in
guard let editor = self.currentEditor() as? NSTextView else { return }
editor.insertionPointColor = color
})
.disposed(by: rx.disposeBag)
}
}