Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Senor Cuete

macrumors 6502
Original poster
Nov 9, 2011
429
31
I have an NSPanel in my program. It has an NSTextField that I set when the panel is initialized. The text has hyperlinked text in it that the user should be able to click on to navigate to a web site and to send an e-mail for support. At one time this worked but now it has stopped.

I load a simple .html file from the project’s resources into NSData from the project’s resources:
Code:
NSString * pathToFile = [[NSBundle mainBundle] pathForResource: @"myFile" ofType: @"html"];
NSData * htmlData = [NSData dataWithContentsOfFile: pathToFile];

Then I set the IBOutlet NSTextField *aString text with
Code:
NSAttributedString *htmlAttributedString = [[NSAttributedString alloc] initWithHTML: htmlData documentAttributes: NULL];
[aString setAttributedStringValue: htmlAttributedString];

The text in the NSTextField is the text I want. The hyperlinked text is highlighted as if the user can click on it but when the cursor is moved over it the cursor doesn’t change and it don’t respond to mouse Clicks. Setting the field to enabled either in Interface Builder or in the code to initialize the text field doesn’t help.

This worked for years but now Apple has changed something and it stopped working. What do I have to do to make this work again?
 
Last edited:

Senor Cuete

macrumors 6502
Original poster
Nov 9, 2011
429
31
I have partially solved this problem. You have to set the NSTextField to:

setAllowsEditingTextAttributes: YES and
setSelectable: YES

BEFORE you

setAttributedStringValue: htmlAttributedString

and you also have to

setEnabled: YES (not mentioned in the documentation)

BEFORE you set the NSTextField to the attributed string

This will make the hyperlinked text work but the cursor still doesn't change from an Ibeam to a hand with a finger as it should when it is over the text.
 

Senor Cuete

macrumors 6502
Original poster
Nov 9, 2011
429
31
I described this inaccurately: The cursor is an arrow but changes to an Ibeam when it's over the hyperlinked text, not the hand with a finger one it should.

Typically the Ibeam cursor is for selecting editable text but changing the NSTextField's editable property to YES or NO doesn't change the cursor's behavior but it highlights the NSTextField when it is set to YES.
 
Last edited:

Senor Cuete

macrumors 6502
Original poster
Nov 9, 2011
429
31
You would think that initializing an NSAttributedString from html would tell MacOS that the NSTextField should be treated as hyperlinked text and the cursor should respond appropriately but it doesn't. To try to force the issue I created an NSDictionary with the NSAttributedStringDocumentType NSHTMLTextDocumentType and initialized the string with this dictionary instead of NULL:
Code:
NSDictionary *myDict = @{@"NSAttributedStringDocumentType" : NSHTMLTextDocumentType};
    NSAttributedString *htmlAttributedString = [[NSAttributedString alloc] initWithHTML: htmlData documentAttributes: &myDict];
This doesn't help. The documentation I linked to above is out-of-date and inaccurate/incomplete. It's labled: Important: This document is no longer being updated. For the latest information about Apple SDKs, visit the documentation website. The documentation website has no information about getting this to work that I can find.

Welcome to MacOS programming - thin, out-of-date documentation.

This is really looking like a bug. Maybe I should report this with Bug Reporter. As if this will help.
 

Senor Cuete

macrumors 6502
Original poster
Nov 9, 2011
429
31
I was able to figure this out. I found out about this by searching in Stack Overflow. You can’t get this information by reading Apple’s documentation. NSTextFields have a bug - they don’t handle cursor changes correctly when the cursor is over hyperlinked text but NSTextViews do. Apple REALLY doesn’t want you to put an NSTextView in your .xib. The only things close in the Xcode pallet of interface objects are several scrollable NSTextViews. When you drag these to an NSPanel you get an NSTextView as a sub-view of a scrollView, a clipView and with two scrollers. Supposedly you could use the Editor->Unembed menu item to get the NSTextView out of this hierarchy but in Xcode 15 you really can’t. Also Xcode won’t let you change objects like NSTextFields to an NSTextView with the Custom Class popup menu in the attributes inspector. The only way to get an NSTextView into a panel is to drag a Custom View into the panel and change the type to an NSTextView with the inspector. I spent a lot of time trying to figure out how to initialize the text in the NSTextView. The documentation for this class doesn’t tell you how to do this. Maybe this is documented in some parent class. I read some posts on Stack Overflow from other developers like me who were frustrated by their inability to figure this out by reading the documentation. The way to set the text in an NSTextView is to get the textStorage property and use the setAttributedString method to initialize it. Also you have to set the Editable property to NO to hide the blinking ibeam cursor that will appear at the end of the HTML text. Here is the code:
Code:
IBOutlet NSTextView *myTextView;

NSString *pathToFile = [[NSBundle mainBundle] pathForResource: @“myString" ofType: @"html"];
NSData *htmlData = [NSData dataWithContentsOfFile: pathToFile];
NSAttributedString *htmlAttributedString = [[NSAttributedString alloc] initWithHTML: htmlData documentAttributes: NULL];
[[myTextView textStorage] setAttributedString: htmlAttributedString];
[htmlAttributedString release]; //not needed if you use ARC
[supportString setEditable: NO]; //hides blinking ibeam cursor.
[supportString setBackgroundColor: [NSColor clearColor]]; //optional properties for appearance
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.