4

使用しようとしている NSScrollView にいくつか問題があり、助けが必要です。NSView、NSScrollView、およびその他のいくつかのガイドとリファレンスを、ここでの質問と cocoadev とともに読みましたが、まだこれらを理解できません。

(私のビュー サブクラスのコードは以下にあります。)

これに関する私の全体的な目標は、PC 専用のニードルポイント チャート メーカーである KGChart のようなインターフェイスです。( KGChart ウェブサイト)

  1. スクロール ビューで描画したものを保持するにはどうすればよいですか? 私の -drawStitch メソッドは、マウス イベント中に実行され、スクロールビューのドキュメント ビューにシンボル (現在は「+」が付いた黒のみ) を持つ四角形を描画します。見えなくなって元に戻すと、消えてしまい、どうにかして保持する必要があります。私の考えは、ステッチを追跡するために 2D 配列を試すことですが、大きなキャンバスではパフォーマンスが低下すると思います (2,000x2,000 を実行したいのですが、500x500 で解決します)。

  2. 私のプログラムを実行している写真を見ると、グリッドの色の違いがわかります。グリッドを描画するコードは -drawRect にあり、色は grayColor として設定されています。プログラムが起動すると、目に見えるグリッドは明るい色ですが、スクロールすると表示されるキャンバスの部分は暗くなります。-drawRect が呼び出されてグリッドが再描画されることに関係していると思いますが、不透明度がすでに 1.0 になっているはずなので、ストロークが暗くなる理由はわかりません。また、元のフレームを完全にスクロールして戻ると、グリッドも暗くなります。

  3. drawRect にないプログラムの最初にグリッドを描画して、再描画されないようにする方法はありますか? -lockFocus でも -awakeFromNib と -initWithFrame を試しましたが、うまくいきませんでした。描画するフレームがなかったので、最初のものはおそらくうまくいかなかったと思います。

  4. 最終的には塗りつぶしツールとか色々調べないといけないので、これはCore Graphicsとか使った方がいいですか、それとも通常のAPIでいいですか?私はCGよりも後者をよく知っているので、後者を使用したいと思いますが、それについても少し読みました.

最終的なメモ: 私はガベージ コレクションを使用しており、ビューとそれが含まれるウィンドウを反転させました。

実行中のプログラムの画像:

実行中のプログラムの画像

    - (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    [self setFrameSize:NSMakeSize(3000, 3000)];
    return self;
}

- (void)drawRect:(NSRect)rect {

    width = [self frame].size.width;
    height = [self frame].size.height;

    [[NSColor grayColor] setStroke];

    NSBezierPath* drawingPath = [NSBezierPath bezierPath];
    [NSBezierPath setDefaultLineWidth:2.0];
    [self addDashStyleToPath:drawingPath];

    int i;

    for( i = 0 ; i <= width ; i=i+30) {
        [drawingPath moveToPoint:NSMakePoint(i, 0)]; 
        [drawingPath lineToPoint:NSMakePoint(i, height)]; 
    } 

    for( i = 0 ; i <= height ; i=i+30) { 
        [drawingPath moveToPoint:NSMakePoint(0,i)]; 
        [drawingPath lineToPoint:NSMakePoint(width, i)]; 
    }

    [drawingPath stroke];

}
-(void)drawStitch{

    NSPoint thisPoint;
    NSPoint fillPoint;
    NSRect fillRect;


    float thisPointX = [self calculatedItemBounds].origin.x + 5.0;
    float thisPointY = [self calculatedItemBounds].origin.y - 8.0;

    float fillPointX = [self calculatedItemBounds].origin.x + 1.0;
    float fillPointY = [self calculatedItemBounds].origin.y + 1.0;

    thisPoint.x = thisPointX;
    thisPoint.y = thisPointY;

    fillPoint.x = fillPointX;
    fillPoint.y = fillPointY;

    fillRect.origin.x = fillPoint.x;
    fillRect.origin.y = fillPoint.y;

    fillRect.size.width = 28;
    fillRect.size.height = 28;

    NSMutableDictionary *theAttributes;

    theAttributes = [[NSMutableDictionary alloc] init];
    [theAttributes setObject: [NSColor whiteColor] forKey:NSForegroundColorAttributeName];
    [theAttributes setObject: [NSFont fontWithName:@"Helvetica" size: 32] forKey: NSFontAttributeName];

    NSString *theString = @"+";
    [self lockFocus];
    [[NSColor blackColor] setFill];
    [NSBezierPath setDefaultLineWidth:2.0];
    [self addDashStyleToPath:[NSBezierPath bezierPathWithRect:[self calculatedItemBounds]]];
    [NSBezierPath fillRect:fillRect];

    NSNumber* myInteger = [NSNumber numberWithInt:310];

    [myArray setObject:myInteger :location.x/30 :location.y/30];
    NSLog(@"%@", [myArray objectInSection:location.x/30 :location.y/30]);
    NSLog(@"%f, %f", location.x/30,location.y/30);

    [theString drawAtPoint:thisPoint withAttributes:theAttributes];
    [self displayIfNeededInRectIgnoringOpacity:[self calculatedItemBounds]];

    [self unlockFocus];
    [theAttributes release];
}

明らかに、私はこれにかなり初心者なので、すべての助けに感謝します!

4

2 に答える 2

2

デフォルトでは、 のコンテンツ ビュー ( のインスタンスNSClipView) は、NSScrollViewスクロール時に既存のレンダリング イメージをコピーすることにより、パフォーマンスの最適化を行います。多くの場合、これで問題なく動作しますが、複雑なカスタム ビューを描画している場合は望ましくない動作になることが多いため、オフにする必要があります。

nib を使用して UI を定義している場合は、IB でスクロール ビューを選択し、[スクロールでコピー] チェックボックスをオフにします。

‑setCopiesOnScroll:次のメソッドを使用して、プログラムでこれを設定できますNSClipView

[[scrollView contentView] setCopiesOnScroll:NO];
于 2011-07-06T02:42:10.777 に答える
1

私はこれを修正したと信じています。これを機能させるには、drawStitch メソッドで lockFocus を使用するのではなく、drawRect で描画を行うようにコードを再配置する必要がありました (MVC の設計について読む必要があります)。また、スクロールビューは最新のベジエ パスのみを再描画するように見えるため、複数の「ステッチ」を作成するには、パスに四角形を追加し続ける必要があります。

于 2011-07-13T03:08:42.150 に答える