Forum Archive

objc_util UITextView and attributed text

SteppenwolfUA

Hi, all

I need a small example of how to use NSMutableAttributedString for attributed text property of UITextView. Can't set text attibutes, get crashes when playing with different options...

Thanx in advance

```
@on_main_thread
def test_001():
red = UIColor.redColor()
font = ObjCClass('UIFont').systemFontOfSize_(30.)
mystring = ObjCClass('NSMutableAttributedString').alloc()
teststring = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt facilisis dapibus.'
mystring.initWithString_(teststring)
#d_red = NSDictionary.alloc().initWithObjectsAndKeys_([red, 'NSForegroundColorAttributeName', None]) # crash
d_red = NSDictionary.alloc().initWithObjects_forKeys_((red,), ('NSForegroundColorAttributeName',))
mystring.setAttributes_range_(d_red, NSRange(10, 15))
tv = ui.TextView()
tvc = ObjCInstance(tv)

#tvc.setAttributedText_(mystring)
# the following line works just fine (why?)
tvc.attributedText = mystring 
tvc.setFont_(font) # ok
tv.present()```
omz

The main problem here is that the constant NSForegroundColorAttributeName actually corresponds to the string 'NSColor'. Unfortunately, it's not really possible to figure this out without Xcode because those are compile-time constants, and they don't exist at runtime (there is no code you could write in Pythonista to translate from NSForegroundColorAttributeName to 'NSColor').

It's possible to use custom attribute names for NSAttributedString (for metadata , custom rendering etc.), so attributes that the text view doesn't understand are simply ignored.

As a general tip, objc_util bridges Python dicts to NSDictionary pretty seamlessly, so instead of the rather complicated NSDictionary.alloc().initWithObjects_forKeys_((red,), ('NSColor',)), you can simply use {'NSColor': red}.

SteppenwolfUA

Hi, @omz

As usual you saved my day!!!

The lesson learned here is I hit the compiled/interpreted language border and you can't always tranlate obj c apis to Python...

How did you figure out the correspondence of NSForegroundColorAttributeName and 'NSColor'? What have I missed here? Any tips?

Many thanks

omz

@SteppenwolfUA What I did was pretty much just compiling a regular Objective-C program (on a Mac), and printing out the value of NSForegroundColorAttributeName. Unfortunately, it's not possible to do this directly on iOS, you basically have to know the values of the constants (in some cases, they're mentioned in the documentation, but this is pretty rare).

SteppenwolfUA

I'm just a bloody beginner and a Windows+iPad user to top it all ))) Still willing to learn and really happy to get support from gurus here! Thank you very much indeed!

SteppenwolfUA

@omz Hi, again! I did some reading of the Apple's docs and found there's a whole bunch of attributes with ..color.. component

NSString *const NSAttachmentAttributeName;
NSString *const NSBackgroundColorAttributeName;
NSString *const NSBaselineOffsetAttributeName;
NSString *const NSExpansionAttributeName;
NSString *const NSFontAttributeName;
NSString *const NSForegroundColorAttributeName;
NSString *const NSKernAttributeName;
NSString *const NSLigatureAttributeName;
NSString *const NSLinkAttributeName;
NSString *const NSObliquenessAttributeName;
NSString *const NSParagraphStyleAttributeName;
NSString *const NSShadowAttributeName;
NSString *const NSStrikethroughColorAttributeName;
NSString *const NSStrikethroughStyleAttributeName;
NSString *const NSStrokeColorAttributeName;
NSString *const NSStrokeWidthAttributeName;
NSString *const NSTextEffectAttributeName;
NSString *const NSUnderlineColorAttributeName;
NSString *const NSUnderlineStyleAttributeName;
NSString *const NSVerticalGlyphFormAttributeName;
NSString *const NSWritingDirectionAttributeName;

Setting the foreground color could be achieved by putting UIColor (which is basically NSColor via toll-free bridging if I'm not mistaken) as value for "NSColor" key in a Python dict. I wonder what would be the names for other predefined keys in the above list. Since you can't use "NSColor" as Python key for all color attributes, there obviously must be different key names for all keys with UIColor, NSNumber etc values.

Many thanks in advance

omz

@SteppenwolfUA With a few exceptions, the values of those constants are the constant name with AttributeName removed, e.g. NSAttachmentAttributeName = 'NSAttachment'. The exceptions are:

  • NSStrikethroughStyleAttributeName = 'NSStrikethrough'
  • NSUnderlineStyleAttributeName = 'NSUnderline'
  • NSVerticalGlyphFormAttributeName = 'CTVerticalForms'
SteppenwolfUA

@omz Thanx a lot, it worked!