ixany
ixany

Reputation: 6040

Displaying text in a NSScrollView (Swift)

Just started to learn Swift and created a little macOS app in which I want to use a NSScrollView to display an attributed String. I’ve tried:

@IBOutlet var ScrollViewOutlet : NSScrollView
var attributedString = NSMutableAttributedString(string: myText)
ScrollViewOutlet.insertText(attributedString)

But that doesn’t seem to work. Feels confusing since doing the exact same with a NSTextView instead works like a charm.

What am I missing here?

Upvotes: 10

Views: 20047

Answers (7)

madx
madx

Reputation: 7203

@IBOutlet weak var scrollView: NSScrollView!

The documentView of the NSScrollView is an NSTextView, so in Swift you can use the following:

let textView : NSTextView? = scrollView?.documentView as? NSTextView
textView?.string = text

Upvotes: 3

ixany
ixany

Reputation: 6040

It seems that the earlier beta versions (which featured Swift) of Xcode had some serious issues with this kind of outlets (as you can see here: http://swiftwtf.tumblr.com/post/88387419568/nstextview). However, since Xcode 6 Beta 6 it works.

textFieldOutlet.textStorage.mutableString.setString("Hello w0rld!")

To handle the String, creating an outlet for the textField instead of the scrollView itself is also a better practice.

Upvotes: 6

Jacksonsox
Jacksonsox

Reputation: 1233

In the following example, I added the scrollView in the interface builder as my starting point.

The following works if you your scrollView/textView is empty/blank OR if you need to append text in front of what is already in the scrollView/textView. If there is already text in the box, the new text is inserted in front of the existing text.

The documentView is an NSTextView

Swift 4.0

@IBOutlet weak var imageDestinationDirectory: NSScrollView!

...

let destinationText = "Text to display"
imageDestinationDirectory.documentView!.insertText(destinationText)

Upvotes: 15

Alexander Borisenko
Alexander Borisenko

Reputation: 1734

Here's how to do it programmatically, with auto layout:

class ViewController: NSViewController {
    let scrollView = NSScrollView()
    let textView = NSTextView()

    override func viewDidLoad() {
        super.viewDidLoad()

        textView.maxSize = NSSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
        textView.autoresizingMask = .width
        textView.isVerticallyResizable = true
        textView.textContainer?.widthTracksTextView = true

        view.addSubview(scrollView)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.documentView = textView

        NSLayoutConstraint.activate([
            scrollView.topAnchor.constraint(equalTo: view.topAnchor),
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ])
    }
}

Upvotes: 3

Robert Waltera
Robert Waltera

Reputation: 67

answer of ixany worked great, but as a beginner it looks me more time to figure it out, that outlet should be done for NSTextView and not for NSTextScroll. NSTextView is hidden inside of NSTextScroll. All Results Field is NSTextScroll in my case and Text View Results is NSTextView

Upvotes: 2

Maxim Veksler
Maxim Veksler

Reputation: 30182

For NSScrollView:

@IBOutlet weak var textScroll: NSScrollView!

Check this out:

let text = textScroll.documentView!.textStorage!!
let attr = NSAttributedString(string: "Hello World")

text.appendAttributedString(attr)

This is very much in spirit of @mrtn.lxo solution, only done for NSScrollView and is using NSAttributedString.

Upvotes: 2

Ken Thomases
Ken Thomases

Reputation: 90551

Apple's has an article about setting up a text view inside a scroll view programmatically. Text System User Interface Layer Programming Guide: Putting an NSTextView Object in an NSScrollView You should read that for greatest understanding, but here's the code:

NSScrollView *scrollview = [[NSScrollView alloc] initWithFrame:[[theWindow contentView] frame]];
NSSize contentSize = [scrollview contentSize];

[scrollview setBorderType:NSNoBorder];
[scrollview setHasVerticalScroller:YES];
[scrollview setHasHorizontalScroller:NO];
[scrollview setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];

theTextView = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, contentSize.width, contentSize.height)];
[theTextView setMinSize:NSMakeSize(0.0, contentSize.height)];
[theTextView setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
[theTextView setVerticallyResizable:YES];
[theTextView setHorizontallyResizable:NO];
[theTextView setAutoresizingMask:NSViewWidthSizable];

[[theTextView textContainer] setContainerSize:NSMakeSize(contentSize.width, FLT_MAX)];
[[theTextView textContainer] setWidthTracksTextView:YES];
[scrollview setDocumentView:theTextView];
[theWindow setContentView:scrollview];
[theWindow makeKeyAndOrderFront:nil];
[theWindow makeFirstResponder:theTextView];

You can then set the text of the text view by operating on its textStorage object:

theTextView.textStorage.attributedString = attributedString;

Upvotes: 5

Related Questions