11

我的一位同事今天来找我,问他如何加载或视图交换一个documentViewNSScrollView以便加载的视图看起来固定在左上角而不是下角。

尽管阅读了 Apple、StackOverflow 和其他各种地方的文档,但他花了一段时间在网上搜索并苦苦挣扎,并没有找到解决方案。

以下是逐个问题:

在 Interface BuilderNSScrollView中将一个拖入项目中。同样在 Interface Builder 中,将两个自定义视图拖到项目中并添加一些文本字段、按钮等。

使用以下IBOutlets 创建一个控制器类(例如 myController):

  • IBOutlet NSScrollView * myScrollView
  • IBOutlet NSView * myCustomView1
  • IBOutlet NSView * myCustomView2

将插座连接到 Interface Builder 中的控件。

创建一个NSView子类来翻转documentView

@implementation myFlippedView

-(id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
    }
    return self;
}

-(void)drawRect:(NSRect)dirtyRect {
    // Drawing code here.
}

-(BOOL)isFlipped {
    return YES;
}

在 Interface Builder 中选择 的documentViewNSScrollView使其成为 的子类myFlippedView。在 Interface Builder 中,您将选择 NSScrollView,然后再次单击它以访问 . documentView,或更改 IB 库以显示树视图并选择NSScrollView.

myController类中使用以下方法交换视图:

-(void)awakeFromNib {

    [myScrollView setDocumentView:myCustomView1];
}

-(IBAction)swapViews:(id)sender {

    if ([myScrollView documentView] == myCustomView1) {

        [myScrollView setDocumentView:myCustomView2];

    } else {

        [myScrollView setDocumentView:myCustomView1];

    }
}

最后将项目中的一个按钮连接到操作swapViews、构建和运行。

问题是没有像 isFlipped 预期的那样解析坐标。

4

2 回答 2

10

有一个简单但显然经常被忽视的原因。

尽管isFlipped在 Interface Builder 中继承了自定义视图,但 documentView 在视图交换中被替换,其中第一个在awakeFromNib.

解决方案是将 myCustomClass1 和 myCustomClass2 子类化为 myFlippedView 类。

执行此操作并对其进行测试,您会注意到视图现在出现在滚动视图的左上方。然而,它又产生了一个新问题。自定义视图中的所有内容现在都是从下到上布局的(因为默认情况下所有NSView布局都是从左下角开始,所以翻转也会翻转它们的坐标)。

幸运的是,这个问题还有另一个简单的解决方法。继续阅读:-)

在 Interface Builder 中,突出显示菜单中的所有控件,myCustomView1然后从Layout菜单中选择 Embed Objects In --> Custom View。根据需要调整大小,对 myCustomView2 执行相同操作并重建。

瞧。内容视图交换并出现NSScrollView在滚动视图的左上角而不是左下角。

于 2011-01-15T01:39:22.760 回答
4

为了正确地使documentView初始对齐到滚动视图的顶部,并且在小于它的剪辑视图时也将其固定到顶部,这对我有用documentView

1 – 在 Interface Builder 中,将 documentView 中的所有控件包含在自定义 NSView实例中。(不是翻转视图)

2 – 创建一个NSView用于 的子类documentView,并覆盖这些方法:

- (BOOL)isFlipped {
    return YES;
}
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize {
CGFloat superViewHeight = self.superview.frame.size.height, height = self.frame.size.height;
    if(superViewHeight>height) {
        [self setFrameOrigin:NSMakePoint(self.frame.origin.x, superViewHeight-height)];
    }
}  

The subclassed view should be the scrollViews' documentView which contains second (normal) NSView that contains all controls.

于 2017-06-06T17:09:22.990 回答