4

Interface Builder を使用すると、複数行の NSTextField (ラベル) とそのすぐ下に NSComboBox を持つ NSView があります。ラベルの高さは動的であるため (たとえば、使用される変換に応じて)、コンボボックスの位置も動的です (コンボボックスの位置は制約を使用してラベルにリンクされているため)。

自動レイアウト後にコンボボックスの正しい位置を取得しようとしています。これを行うのは非常に簡単なはずですが、何らかの理由でこれを機能させることができません。[NSView FittingSize] を使用してラベルのサイズ変更を取得できますが、[NSView フレーム] が間違った Y 位置を返しています (IB で使用されている位置を返すだけです)。私の質問は基本的に、自動レイアウト後に再配置されたフレームを取得する方法ですか?

参考までに、上書きされた [NSView loadView] メソッドでフレーム プロパティを要求しています。

ご協力いただきありがとうございます!

4

2 に答える 2

1

NSView のフレームを観察します。

@implementation MyViewController {
    BOOL _isViewFrameKVORegistered;
}

- (void)loadView
{
    [super loadView];

    [self registerViewFrameKVO];
}

- (void)willChangeViewFrame
{
    NSLog(@"will change frame");
}

- (void)didChangeViewFrame
{
    NSLog(@"did change frame");
}

# pragma mark KVO
- (void)registerViewFrameKVO {
    [self addObserver:self forKeyPath:@"view.frame" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionPrior context:NULL];
    _isViewFrameKVORegistered = YES;
}

- (void)unregisterViewFrameKVO {
    [self removeObserver:self forKeyPath:@"view.frame"];
    _isViewFrameKVORegistered = NO;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if([keyPath isEqualToString:@"view.frame"]) {
        if ([change[@"notificationIsPrior"] boolValue]) {
            [self willChangeViewFrame];
        } else {
            [self didChangeViewFrame];
        }
    }
}

- (void)dealloc
{
    [self unregisterViewFrameKVO];
}

@end

それが役に立てば幸い。

于 2013-10-28T14:30:09.830 に答える
1

NSView には loadView メソッドがありません。NSViewController の loadView のことですか?もしそうなら、実際のフレームを取得するには時期尚早だと思います。updateConstraints をオーバーライドしてそこにチェックインしてみてください。iOS では、viewDidAppear でこれを行います: -- OS X でこれに相当するものが何であるかはわかりません。別の可能性は、viewDidMoveToWindow にあります。

于 2013-02-09T19:33:57.297 に答える