【问题标题】:Custom insertion point for NSTextViewNSTextView 的自定义插入点
【发布时间】:2014-07-18 19:12:25
【问题描述】:

我正在通过覆盖 -(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];
    }
}

【问题讨论】:

  • flag 为 false 时,您是否尝试清除插入点区域(填充背景等)?

标签: cocoa customization nstextview caret


【解决方案1】:

问题是调用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 可以快速而肮脏地清除工件。

【讨论】:

    【解决方案2】:

    我不做应用商店,但我想知道这个“棘手”的小技巧是否会让一个无证电话在 Apple 的雷达下飞行。基本上,您有一个无害命名的方法,它实现了被覆盖的未记录调用所做的工作。然后,您使用 Obj-C 运行时将您的实现交换为未记录的实现。您对 SEL 进行 ROT-13,以便文本分析不会在任何地方看到未记录的方法名称。我不知道苹果会不会抓住这个!

    不知道这是否有帮助,但我认为这会很有趣。

    (我知道在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-18
      • 1970-01-01
      • 2014-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多