15

NSScrollView をドキュメント ビューの中央に配置する方法の例はたくさんあります。以下に 2 つの例を示します (非常によく似ているため、誰かが出典を明記せずに誰かをコピーしていますが、そこにどのようにあるのかという点です) .com/devosoft/avida/blob/master/apps/viewer-macos/src/main/CenteringClipView.h

これは通常、NSClipView をサブクラス化し、オーバーライドすることによって行われます。

- (NSPoint)constrainScrollPoint:(NSPoint)newOrigin;

ただし、この方法は Mac OS X 10.9 以降では推奨されていません。

今、我々に何ができるだろうか?いやいや~!

4

4 に答える 4

26

ええと、答えは簡単で、それらほど肥大化しているわけではありません。とにかく、それらはダブルタップ拡大では機能しません。

これはそうです。それだけで機能します。必要に応じて調整をカスタマイズすることもできます。

@implementationでは、constraintBoundsRectのオーバーライドを実装するだけで済みます。

- (NSRect)constrainBoundsRect:(NSRect)proposedClipViewBoundsRect {

    NSRect constrainedClipViewBoundsRect = [super constrainBoundsRect:proposedClipViewBoundsRect];

    // Early out if you want to use the default NSClipView behavior.
    if (self.centersDocumentView == NO) {
        return constrainedClipViewBoundsRect;
    }
    
    NSRect documentViewFrameRect = [self.documentView frame];
                
    // If proposed clip view bounds width is greater than document view frame width, center it horizontally.
    if (proposedClipViewBoundsRect.size.width >= documentViewFrameRect.size.width) {
        // Adjust the proposed origin.x
        constrainedClipViewBoundsRect.origin.x = centeredCoordinateUnitWithProposedContentViewBoundsDimensionAndDocumentViewFrameDimension(proposedClipViewBoundsRect.size.width, documentViewFrameRect.size.width);
    }

    // If proposed clip view bounds is hight is greater than document view frame height, center it vertically.
    if (proposedClipViewBoundsRect.size.height >= documentViewFrameRect.size.height) {
        
        // Adjust the proposed origin.y
        constrainedClipViewBoundsRect.origin.y = centeredCoordinateUnitWithProposedContentViewBoundsDimensionAndDocumentViewFrameDimension(proposedClipViewBoundsRect.size.height, documentViewFrameRect.size.height);
    }

    return constrainedClipViewBoundsRect;
}


CGFloat centeredCoordinateUnitWithProposedContentViewBoundsDimensionAndDocumentViewFrameDimension
(CGFloat proposedContentViewBoundsDimension,
 CGFloat documentViewFrameDimension )
{
    CGFloat result = floor( (proposedContentViewBoundsDimension - documentViewFrameDimension) / -2.0F );
    return result;
}

@interface では、1 つのプロパティを追加するだけです。これにより、センタリングを使用しないことができます。ご想像のとおり、場合によってはセンタリングをオフにしたい条件付きロジックがあるかもしれません。

@property BOOL centersDocumentView;

また、必ずこれをに設定BOOLするYESNO、オーバーライドしてください

initWithFrameinitWithCoder:

そのため、既知のデフォルト値から作業できます。

子供たちを覚えておい initWithCoder:てください。必要なことを行い、ペン先にビューのクラスを設定できます。自分のものの前にスーパーを呼び出すことを忘れないでください!

もちろん、10.9 より前のものをサポートする必要がある場合は、他のものを実装する必要があります。

(おそらく他の人が持っているほどではありませんが...)

EDIT:他の人が指摘したように、AppleはSwiftのサンプルコードを持っています(2016年からなので、現在のSwiftではないかもしれません:D)https://developer.apple.com/library/archive/samplecode/Exhibition/Listings/Exhibition_CenteringClipView_swift .html

于 2014-02-27T14:54:29.663 に答える
1

上記の uchuugaka による回答は非常にうまく機能し、指摘されているように、古いソリューションよりもはるかに単純です。

上記のコードは関数centeredCoordinateUnitWithProposedContentViewBoundsDimensionAndDocumentViewFrameDimension()を呼び出しますが、このソースは提供されていません。

関数は簡単ですが、完全を期すために実装を次に示します。

CGFloat centeredCoordinateUnitWithProposedContentViewBoundsDimensionAndDocumentViewFrameDimension( CGFloat clipDimension, CGFloat docDimension)
{
    CGFloat newOrigin;
    newOrigin = roundf((docDimension - clipDimension) / 2.0);
    return newOrigin;
}
于 2014-03-31T06:37:30.553 に答える