为 NSTextView 设置占位符字符串
Set the placeholder string for NSTextView
有没有办法像 NSTextField
那样为 NSTextView
设置占位符字符串?我检查了 属性 但没找到。我搜索了一些问题,但没有合适的解释。
我在网上找到了这个答案。 Philippe Mougin 做了这个。
static NSAttributedString *placeHolderString;
@implementation TextViewWithPlaceHolder
+(void)initialize
{
static BOOL initialized = NO;
if (!initialized)
{
NSColor *txtColor = [NSColor grayColor];
NSDictionary *txtDict = [NSDictionary dictionaryWithObjectsAndKeys:txtColor, NSForegroundColorAttributeName, nil];
placeHolderString = [[NSAttributedString alloc] initWithString:@"This is my placeholder text" attributes:txtDict];
}
}
- (BOOL)becomeFirstResponder
{
[self setNeedsDisplay:YES];
return [super becomeFirstResponder];
}
- (void)drawRect:(NSRect)rect
{
[super drawRect:rect];
if ([[self string] isEqualToString:@""] && self != [[self window] firstResponder])
[placeHolderString drawAtPoint:NSMakePoint(0,0)];
}
- (BOOL)resignFirstResponder
{
[self setNeedsDisplay:YES];
return [super resignFirstResponder];
}
@end
Swift 2.0
var placeHolderTitleString: NSAttributedString = NSAttributedString(string: "Place Holder Value", attributes: [NSForegroundColorAttributeName : NSColor.grayColor()])
override func becomeFirstResponder() -> Bool {
self.needsDisplay = true
return super.becomeFirstResponder()
}
override func drawRect(rect: NSRect) {
super.drawRect(rect)
if (self.string! == "") {
placeHolderString.drawAtPoint(NSMakePoint(0, 0))
}
}
Swift 4
事实证明,NSTextView
中似乎已经有一个 placeholderAttributedString
属性 没有公开。因此,您可以简单地在自己的子类中实现它并获得默认的占位符行为(类似于 NSTextField
)。
class PlaceholderTextView: NSTextView {
@objc var placeholderAttributedString: NSAttributedString?
}
而且如果这个属性将来可以使用,你只需要使用NSTextView而不是这个子类。
找这个。这可能是更好的方法!
final class CustomTextView: NSTextView {
private var placeholderAttributedString: NSAttributedString? = NSAttributedString(string: "Your placeholder string here")
private var placeholderInsets = NSEdgeInsets(top: 0.0, left: 4.0, bottom: 0.0, right: 4.0)
override func becomeFirstResponder() -> Bool {
self.needsDisplay = true
return super.becomeFirstResponder()
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
guard string.isEmpty else { return }
placeholderAttributedString?.draw(in: dirtyRect.insetBy(placeholderInsets))
}
}
extension NSRect {
func insetBy(_ insets: NSEdgeInsets) -> NSRect {
return insetBy(dx: insets.left + insets.right, dy: insets.top + insets.bottom)
.applying(CGAffineTransform(translationX: insets.left - insets.right, y: insets.top - insets.bottom))
}
}
如果您使用故事板,最好的方法是放置一个 NSTextView
并将其值绑定到一个
@objc dynamic var myString: String?
属性 在你的控制器中。然后,在绑定检查器中,您可以设置一个 Null Placeholder
值,文本视图将使用该值,而您根本不必使用任何显式私有 API。
有没有办法像 NSTextField
那样为 NSTextView
设置占位符字符串?我检查了 属性 但没找到。我搜索了一些问题,但没有合适的解释。
我在网上找到了这个答案。 Philippe Mougin 做了这个。
static NSAttributedString *placeHolderString;
@implementation TextViewWithPlaceHolder
+(void)initialize
{
static BOOL initialized = NO;
if (!initialized)
{
NSColor *txtColor = [NSColor grayColor];
NSDictionary *txtDict = [NSDictionary dictionaryWithObjectsAndKeys:txtColor, NSForegroundColorAttributeName, nil];
placeHolderString = [[NSAttributedString alloc] initWithString:@"This is my placeholder text" attributes:txtDict];
}
}
- (BOOL)becomeFirstResponder
{
[self setNeedsDisplay:YES];
return [super becomeFirstResponder];
}
- (void)drawRect:(NSRect)rect
{
[super drawRect:rect];
if ([[self string] isEqualToString:@""] && self != [[self window] firstResponder])
[placeHolderString drawAtPoint:NSMakePoint(0,0)];
}
- (BOOL)resignFirstResponder
{
[self setNeedsDisplay:YES];
return [super resignFirstResponder];
}
@end
Swift 2.0
var placeHolderTitleString: NSAttributedString = NSAttributedString(string: "Place Holder Value", attributes: [NSForegroundColorAttributeName : NSColor.grayColor()])
override func becomeFirstResponder() -> Bool {
self.needsDisplay = true
return super.becomeFirstResponder()
}
override func drawRect(rect: NSRect) {
super.drawRect(rect)
if (self.string! == "") {
placeHolderString.drawAtPoint(NSMakePoint(0, 0))
}
}
Swift 4
事实证明,NSTextView
中似乎已经有一个 placeholderAttributedString
属性 没有公开。因此,您可以简单地在自己的子类中实现它并获得默认的占位符行为(类似于 NSTextField
)。
class PlaceholderTextView: NSTextView {
@objc var placeholderAttributedString: NSAttributedString?
}
而且如果这个属性将来可以使用,你只需要使用NSTextView而不是这个子类。
找这个。这可能是更好的方法!
final class CustomTextView: NSTextView {
private var placeholderAttributedString: NSAttributedString? = NSAttributedString(string: "Your placeholder string here")
private var placeholderInsets = NSEdgeInsets(top: 0.0, left: 4.0, bottom: 0.0, right: 4.0)
override func becomeFirstResponder() -> Bool {
self.needsDisplay = true
return super.becomeFirstResponder()
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
guard string.isEmpty else { return }
placeholderAttributedString?.draw(in: dirtyRect.insetBy(placeholderInsets))
}
}
extension NSRect {
func insetBy(_ insets: NSEdgeInsets) -> NSRect {
return insetBy(dx: insets.left + insets.right, dy: insets.top + insets.bottom)
.applying(CGAffineTransform(translationX: insets.left - insets.right, y: insets.top - insets.bottom))
}
}
如果您使用故事板,最好的方法是放置一个 NSTextView
并将其值绑定到一个
@objc dynamic var myString: String?
属性 在你的控制器中。然后,在绑定检查器中,您可以设置一个 Null Placeholder
值,文本视图将使用该值,而您根本不必使用任何显式私有 API。