iOS 7: NSString.DrawString() chokes on UIStringAttributes

When using the new DrawString() method added in iOS 7 that takes an UIStringAttributes argument, I get a runtime Exception (Xamarin.iOS 7.0.5.2)

Code

UIStringAttributes attributes = new UIStringAttributes{ForegroundColor = UIColor.FromRGB(1,0,0)};

new NSString("Test").DrawString(new PointF(10, 10), attributes);

The exception I get is

Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[__NSCFString drawAtPoint:withAttributes:]: unrecognized selector sent to instance 0x14839730

Any ideas why this is happening?

Posts

  • BenDodsonBenDodson USMember ✭✭

    Did you ever figure this issue out?

  • SteveFlackSteveFlack GBMember ✭✭

    It's broken for me too.

  • RolfBjarneKvingeRolfBjarneKvinge USXamarin Team Xamurai

    I can only reproduce this exception if I run on a device with iOS 6 or earlier (which is expected, since the API was introduced in iOS 7).

    Can you please verify that you're executing on an iOS 7 device/simulator?

  • I'm getting the same error running on iOS 7 (on an iPad 2):

    Apr 2 17:46:33 RowingInMotionMobileBoatAppiOS[945] : Unhandled managed exception: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[__NSCFString drawInRect:withAttributes]: unrecognized selector sent to instance 0x14d055b0 (MonoTouch.Foundation.MonoTouchException)
    at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:void_objc_msgSend_RectangleF_IntPtr (intptr,intptr,System.Drawing.RectangleF,intptr)
    at MonoTouch.UIKit.NSStringDrawing.WeakDrawString (MonoTouch.Foundation.NSString This, RectangleF rect, MonoTouch.Foundation.NSDictionary attributes) [0x00000] in :0
    at MonoTouch.UIKit.NSStringDrawing.DrawString (MonoTouch.Foundation.NSString This, RectangleF rect, MonoTouch.UIKit.UIStringAttributes attributes) [0x00000] in :0
    at RowingInMotion.Mobile.BoatApp.iOS.Adapter.GLFontAdapter.CreateTextureFont (System.String text, Single fontSize, System.Int32& textureWidth, System.Int32& textureHeight) [0x00000] in :0
    at RowingInMotion.Mobile.BoatApp.Native.OpenGl.TextureLoader.CreateTextureFont (System.String text, Single fontSize, System.Int32& textureWidth, System.Int32& textureHeight) [0x00000] in :0

  • JohnHJohnH GBMember ✭✭✭✭✭
    edited April 2014

    @RolfBjarneKvinge‌
    Im getting the same error in iOS7 on an iPhone 5s.
    I see that DrawString is actually just an extension method, calling WeakDrawString fails in the same way, as I'd expect it to.

    Xamarin.iOS
    Version: 7.2.0.2 (Business Edition)
    Apple Developer Tools
    Xcode 5.1 (5084)

  • RolfBjarneKvingeRolfBjarneKvinge USXamarin Team Xamurai

    @JohnHair: I've found it, it's a selector typo (drawInRect:withAttributes vs drawInRect:withAttributes: (note the trailing colon)).

    Note that there are several DrawString overloads, not all have this problem.

  • JohnHJohnH GBMember ✭✭✭✭✭

    @RolfBjarneKvinge‌ nicely done, I saw there were other overloads but I moved onto a different piece of work.
    I actually need the RectangleF, UIStringAttributes sig version as I am relying on the text to be word wrapped within a certain space. Any idea when this will get into the Stable channel? Or anything I can do write now to try to fix it myself? Would be good for me to learn how I can map to a selector anyway :)

  • YellowbeardYellowbeard USMember
    edited April 2014

    here's an example (it's for drawAtPoint:withAttributes: but you get the idea)

    NSString target = new NSString("Test"); Selector selector = new Selector("drawAtPoint:withAttributes:"); Messaging.void_objc_msgSend_PointF_IntPtr(target.Handle, selector.Handle, rect.Location, stringAttributes.Dictionary.Handle);

    Dirk

  • JohnHJohnH GBMember ✭✭✭✭✭

    Thank you for the example Dirk! Wow, that was incredibly easy, I am now using the selector I need! Very cool.

    Cheers
    John

  • SteveScalponeSteveScalpone USMember

    I'm hitting this too. Is there a fix in the works?

  • Here is a fix that works for me:

    private static void DrawStringWorkaround(NSString text, RectangleF rect, UIStringAttributes attributes)
    {
        Selector selector = new Selector("drawInRect:withAttributes:");
        Messaging.void_objc_msgSend_RectangleF_IntPtr(text.Handle, selector.Handle, rect, attributes.Dictionary.Handle);
    }
    
  • BernieHabermeierBernieHabermeier USUniversity ✭✭

    Related to this. Version: 8.10.0.267 (Business Edition) seems to not have this version at all:
    https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/NSString_UIKit_Additions/index.html#//apple_ref/occ/instm/NSString/drawInRect:withAttributes:

    NSString.DrawString(CGPoint, UIStringAttributes) seems to be missing.

    Which is hilarious, because if you look at the decl here:

    [Availability(Introduced = Platform.iOS_2_0, Deprecated = Platform.iOS_7_0, Message = "Use NSString.DrawString(CGPoint, UIStringAttributes) instead.")]
    public static CGSize DrawString(this string This, CGPoint point, UIFont font);

    It seems to make mention of NSString.DrawString(CGPoint, UIStringAttributes)

    Am I just confused?
    What's the p/invoke fix for this?
    When will Xamarin add this to iOS?

Sign In or Register to comment.