8

I'm changing the insertion point size by overriding -(void)drawInsertionPointInRect:(NSRect)aRect color:(NSColor *)aColor turnedOn:(BOOL)flag, But it doesn't handle the first blink (when you move the insertion point, it goes back to normal)

I managed to handle the first blink by overriding the private method - (void)_drawInsertionPointInRect:(NSRect)aRect color:(NSColor *)aColor.

But this is not a solution for me since overriding the private method will result in being decline by App Store. I want the app to be in App Store. I see Apps like iAWriter and Writeroom have a custom insertion point and they are in App store.

Does anyone know how they managed to do this, or a better way rather than overriding the private method?

Thanks.

- (void)_drawInsertionPointInRect:(NSRect)aRect color:(NSColor *)aColor
{
    aRect.size.width = 3.0;
    [aColor set];
    [NSBezierPath fillRect:aRect];
}

- (void)drawInsertionPointInRect:(NSRect)aRect color:(NSColor *)aColor turnedOn:(BOOL)flag
{
    if(flag) {
        aRect.size.width = 3.0;
        [aColor set];
        [NSBezierPath fillRect:aRect];
    }
    else {
        [self setNeedsDisplayInRect:[self visibleRect] avoidAdditionalLayout:NO];
    }
}
Jensen
  • 1,653
  • 4
  • 26
  • 42

2 Answers2

6

The problem is the clipping path that is in effect when drawInsertionPointInRect is called.

- (void)drawInsertionPointInRect:(NSRect)rect color:(NSColor *)color turnedOn:(BOOL)flag {
    rect.size.width = 8.0;
    NSBezierPath * path = [NSBezierPath bezierPathWithRect:rect];
    [path setClip]; // recklessly set the clipping area (testing only!)
    [path fill];
}

Note that the above code will leave artifacts (in my testing drawInsertionPointInRect is not called to clear the insertion point, only to draw it). Use setDrawsBackground:YES for a quick and dirty way to clear the artifacts.

Sam Jacobson
  • 431
  • 5
  • 7
0

I don't do app store, but I wonder if this "tricky" little hack would let an undocumented call fly under Apple's radar. Basically you have an innocuously-named method that implements the work the overridden undocumented call does. Then you use the Obj-C runtime to swap your implementation into the undocumented one. You ROT-13 the SELs so that textual analysis won't see the undocumented method name anywhere. I don't know if Apple would catch this or not!

Dunno if this helps, but I thought it'd be a bit of fun.

(I know there far faster and cleverer ways to do ROT-13 in Obj-C, than my one-off implementation below.)

@implementation MyTextView
-(void)nothingToSeeHere:(NSRect)aRect
       heyLookAtThat:(NSColor*)aColor
{
  aRect.size.width = 3.0;
  [aColor set];
  [NSBezierPath fillRect:aRect];
}

#define dipirRot @"_qenjVafregvbaCbvagVaErpg:pbybe:"
#define ntshRot @"abguvatGbFrrUrer:urlYbbxNgGung:"
+(void)initialize
{
  if (self == [MyTextView class])
  {
    SEL dipir = NSSelectorFromString([NSString rot13:dipirRot]);
    SEL ntsh = NSSelectorFromString([NSString rot13:ntshRot]);
    Method dipirMethod = class_getInstanceMethod([self class], dipir);
    Method ntshMethod = class_getInstanceMethod([self class], ntsh);
    IMP ntshIMP = method_getImplementation(ntshMethod);
    (void)method_setImplementation(dipirMethod, ntshIMP);
  }
}


@implementation NSString (Sneaky)
+(NSString*)rot13:(NSString*)s
{
  NSMutableString* ms = [[NSMutableString alloc] init];
  unsigned len = [s length];
  unsigned i;
  for (i = 0; i < len; i++)
  {
    unichar c = [s characterAtIndex:i];
    if (c <= 122 && c >= 97) c += (c + 13 > 122)? -13:13;
    else if(c <= 90 && c >= 65) c += (c + 13 > 90)? -13:13;
    [ms appendFormat:@"%C", c];
  }
  NSString* ret = [NSString stringWithString:ms];
  [ms release];
  return ret;
}
@end
K8TIY
  • 74
  • 2