Set the placeholder string for NSTextView

前端 未结 4 1893
鱼传尺愫
鱼传尺愫 2020-12-16 21:12

Is there any way to set the placeholder string for NSTextView like that in NSTextField? I have checked the property but couldn\'t find it. I have s

相关标签:
4条回答
  • 2020-12-16 21:41

    I found this answer online. Philippe Mougin made this.

    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
    
    0 讨论(0)
  • 2020-12-16 21:48

    Look for this. It's may be a better approach!

    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))
        }
    }
    
    0 讨论(0)
  • 2020-12-16 21:50

    Swift 4

    As it turns out, there already seems to be a placeholderAttributedString property in NSTextView that isn't exposed publicly. Thus, you can simply implement it in your own subclass and get the default placeholder behaviour (similar to NSTextField).

    class PlaceholderTextView: NSTextView {
         @objc var placeholderAttributedString: NSAttributedString?
    }
    

    And if this property will be made available in the future, you only need to use NSTextView instead of this subclass.

    0 讨论(0)
  • 2020-12-16 21:58

    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))
        }
    }
    
    0 讨论(0)
提交回复
热议问题