gpt4 book ai didi

cocoa - 如何在 ScrollView 中设置多个可扩展部分

转载 作者:行者123 更新时间:2023-12-03 17:06:51 24 4
gpt4 key购买 nike

我需要一个类似于 IB 的检查器的布局,其中有多个可扩展部分,通过显示三角形扩展,所有这些都包含在 ScrollView 中。

如果只需要一个可扩展部分,我已经在那里了:我将可扩展部分放入 NSBox 中,为盒子及其上方的所有内容提供顶部支柱,但没有底部支柱,并为其下方的所有内容提供底部支柱但没有顶部支柱。然后,我设置显示三角形的操作以显示/隐藏该框并调整 ScrollView 文档 View 的框架大小。

但是似乎没有办法为多个盒子设置支柱。关闭显示三角形会留下间隙,或者盒子会相互滑动。

我确实看过 NSOutlineView,但那是一个表格;它不能有像组合框和按钮这样的 subview 。 (或者也许可以,如果我制作自定义单元格,这是我尚未完成的事情 - 但我怀疑它们不适合全功能布局。)

有人能指出我正确的方向吗?

最佳答案

如果其他人遇到这个设计挑战,我将发布我想出的 IBAction。

该方案使用常规的、非翻转的 View 。也就是说,原点位于左下角。当 docSize 更改时,会在顶部添加或删除空间。

虽然对于单个显示三角形,某些控件需要顶部支柱,有些需要底部支柱,但对于此方案,所有控件都必须具有顶部和底部支柱。否则他们会自动调整自己,把一切都扔掉。

如最后所述,完全滚动到底部时会遇到相当大的挑战。但这是另一章了……

/**
Action called upon clicking a disclosure triangle.
Hides or discloses the box associated with the disclosure triangle.
*/
- (IBAction) discloseBox:(id)sender {

// Determine which box is governed by this disclosure triangle.
NSBox *boxTarget;
switch ([sender tag]) {
case kDT_Source:
boxTarget = self.boxSourceInfo;
break;
case kDT_Tweak:
boxTarget = self.boxTweak;
break;
case kDT_Series:
boxTarget = self.boxSeries;
break;
case kDT_Abbrevs:
boxTarget = self.boxAbbreviations;
break;
case kDT_Flag:
boxTarget = self.boxFlaggingAndComments;
break;
default:
break;
}

// Get size info on the content with and without the box.
NSView *docView = [self.svEditorMain documentView];
NSSize docSize = [docView frame].size;
CGFloat fHeightChange = [boxTarget frame].size.height;

// Before actually changing the content size, record what point is currently at the top of the window.
CGFloat dropFromTop_preChange = [self getCurrentDropFromTop];

// If the state is now on, make the box visible.
// If the state is now off, hide the box and make the height change negative.
switch ([sender state]) {
case NSOnState:
[boxTarget setHidden:NO];
break;
case NSOffState:
[boxTarget setHidden:YES];
fHeightChange *= -1;
break;
default:
break;
}
// Use the height change to prepare the adjusted docSize, but don't apply it yet.
NSSize adjustedDocSize = NSMakeSize(docSize.width, (docSize.height + fHeightChange));

// Make sure the adjustees array is populated.
[self populateVerticalAdjusteesArray];

// If the height change is positive, expand the content size before adjusting the origins, so that the origins will have space to move up into. (Space will be added at top.)
if (fHeightChange > 0)
[docView setFrameSize:adjustedDocSize];

// Get the current, pre-change Y origin of the target box.
CGFloat boxOriginY_preChange = [boxTarget frame].origin.y;
// Loop through the adjustees, adjusting their height.
NSControl *control;
CGFloat originX;
CGFloat originY;

for (NSUInteger ui = 0; ui < [self.carrVerticalAdjustees count]; ++ui) {
control = [self.carrVerticalAdjustees objectAtIndex:ui];
originY = [control frame].origin.y;
// Adjust all controls that are above the origin Y of the target box (but do nothing to the target box itself).
// Since coordinate system places origin at lower left corner, higher numbers are higher controls.
if (originY > boxOriginY_preChange) {
originX = [control frame].origin.x; // get originX just so you can assemble a new NSPoint
originY += fHeightChange;
[control setFrameOrigin:NSMakePoint(originX, originY)];
}
// Since the array was assembled in order from top down, once a member is encountered whose origin is below the target's, we're done.
else
break;
}

// If the height change is negative, contract the content size only now, after the origins have all been safely adjusted downwards. (Space will be removed at top.)
if (fHeightChange < 0)
[docView setFrameSize:adjustedDocSize];

// Left to its own devices, the scroller will maintain the old distance from the bottom, so whatever is under the cursor will jump up or down. To prevent this, scroll the content to maintain the old distance from the TOP, as recorded above.
// (This won't work if user is already scrolled to the bottom and then collapses a box. The only way to maintain the scroll position then would be to add blank space at the bottom, which would require moving the origin of all the content up. And then you would want to reverse those changes as soon as the blank space scrolled back out of view, which would require adding some trackers and monitoring NSViewBoundsDidChangeNotification.)
[self scrollMainTo:dropFromTop_preChange];

}

关于cocoa - 如何在 ScrollView 中设置多个可扩展部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5406981/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com