NSTextView的自定义插入点

时间:2013-03-26 21:36:09

标签: cocoa customization nstextview caret

我正在通过覆盖-(void)drawInsertionPointInRect:(NSRect)aRect color:(NSColor *)aColor turnedOn:(BOOL)flag更改插入点大小,但它不处理第一次闪烁(当您移动插入点时,它会恢复正常)

我设法通过覆盖私有方法- (void)_drawInsertionPointInRect:(NSRect)aRect color:(NSColor *)aColor来处理第一次闪烁。

但这对我来说不是一个解决方案,因为重写私有方法会导致App Store下降。我希望该应用程序在App Store中。我看到像iAWriter和Writeroom这样的应用程序有一个自定义插入点,它们在App Store中。

是否有人知道他们是如何设法做到的,或者是更好的方式而不是覆盖私有方法?

感谢。

- (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];
    }
}

2 个答案:

答案 0 :(得分:6)

问题是调用drawInsertionPointInRect时生效的剪切路径。

- (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];
}

请注意,上面的代码会留下瑕疵(在我的测试中,不会调用drawInsertionPointInRect来清除插入点,只是为了绘制它)。使用setDrawsBackground:YES以快速而脏的方式清除工件。

答案 1 :(得分:0)

我不做应用程序商店,但我想知道这是否"棘手"小黑客会让一个无证的电话在Apple的雷达下飞行。基本上你有一个无害命名的方法来实现被覆盖的未记录的调用所做的工作。然后使用Obj-C运行时将您的实现交换到未记录的实现。你ROT-13 SELs,所以文本分析不会在任何地方看到未记录的方法名称。我不知道Apple是否会抓住这个!

Dunno如果这有帮助,但我认为它会有点乐趣。

(我知道在Obj-C中进行ROT-13的速度和方法要比我下面的一次性实施更快更聪明。)

@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