NSScrollview 不以编程方式滚动?
Posted
技术标签:
【中文标题】NSScrollview 不以编程方式滚动?【英文标题】:NSScrollview not scrolling programmatically? 【发布时间】:2013-10-30 05:32:53 【问题描述】:注意:水平和垂直滚动条都在屏幕上可见并且工作正常。但我不能让它们以编程方式移动。
我正在开发一个可可桌面应用程序。我在我的 Mainmenu.xib 文件中使用 NSScrollview,我正在它的所有者中创建一个出口,即 Appdelegate.h 。 这里是出口
@property(nonatomic,retain) IBOutlet NSScrollView* scrollview;
当我尝试从界面生成器设置我的 NSScrollview 的新引用出口并将线路转到文件所有者时,我只看到一个选项“委托”。我没有看到出口滚动视图。 所以我将滚动视图连接到文件所有者中的委托(因为我看不到滚动视图出口)。
现在我正在尝试在我的代码中进行自动滚动。这是代码
for(int a=0;a<10000;a++)
NSPoint pointToScrollTo = NSMakePoint ( 100+a,100+a ); // Any point you like.
[[self.scrollview contentView] scrollToPoint: pointToScrollTo];
[self.scrollview reflectScrolledClipView: [self.scrollview contentView]];
此代码不起作用,滚动条不会自动滚动。
我正在尝试用这段代码制作一个缓慢的滚动动画。
【问题讨论】:
【参考方案1】:NSClipView 有一个scrollToPoint: 方法,可用于以编程方式滚动:
- (IBAction)scrollToMid:(id)sender
CGFloat midYPoint = [self.scrollView contentView].frame.size.height/2.0;
[[self.scrollView contentView] scrollToPoint:NSMakePoint(0.0, midYPoint)];
[self.scrollView reflectScrolledClipView:[self.scrollView contentView]];
如果你想要动画滚动,你必须通过动画代理设置boundsOrigin
。 (因为NSScrollView
和NSClipView
都没有暴露动画滚动点属性)
- (IBAction)scrollToMidAnimated:(id)sender
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:2.0];
NSClipView* clipView = [self.scrollView contentView];
NSPoint newOrigin = [clipView bounds].origin;
newOrigin.y = [self.scrollView contentView].frame.size.height/2.0;
[[clipView animator] setBoundsOrigin:newOrigin];
[NSAnimationContext endGrouping];
【讨论】:
谢谢你的方法有效。投票并被选为最佳答案! 有没有办法限制用户手动滚动? 我不想让用户滚动。我隐藏了滚动条,但用户仍然可以使用鼠标滚动器滚动。这可能吗? 我不希望滚动视图响应用户交互。我只想以编程方式滚动 有没有办法给 clipview 提供最后的分数?即我可以将 x,y 点指定给剪辑视图,而不是给出帧的原点吗?【参考方案2】:更好的方法是翻转视图。我一直致力于将滚动视图置于顶部。
-(void)scrollToTop:(NSScrollView *)scrollView
NSPoint newScrollOrigin;
if ([[scrollView documentView] isFlipped])
newScrollOrigin=NSMakePoint(0.0,0.0);
else
newScrollOrigin=NSMakePoint(0.0,NSMaxY([[scrollView documentView] frame]) -NSHeight([[scrollView contentView] bounds]));
[[scrollView documentView] scrollPoint:newScrollOrigin];
应该在windowDidLoad
中调用以获取位置。
-(void)windowDidLoad
[super windowDidLoad];
[self scrollToTop:_myScroll];
【讨论】:
【参考方案3】:在文件所有者的身份检查器中,检查其类。它必须设置为 NSApplication.
您必须将其更改为 AppDelegate
才能获得可以连接滚动视图的插座 scrollview
。
但更好的选择是在您的 xib 中有一个 NSObject
并将其类设置为 AppDelegate
。 (但是 xcode 默认创建它,检查是否存在项目“AppDelegate
”在存在FileOwner
的“占位符”下方的“对象”框中)。现在将引用出口线从您的scrollview
拖到该对象。它将显示您的 Appdelegate
类的 IBOutlet
对象名称。
更新: 您不能使用 for 循环创建慢速动画。 for 循环非常快,以至于您只能看到最终结果,而不是完整的滚动。您需要使用核心动画来进行慢速动画或使用 NSTimer 来延迟滚动以使其变慢。
另外请尝试使用 [scrollview documentView] 代替 [scrollview contentView] 。虽然没试过。
好的,我已经完成了,这是最终结果 如果您的滚动条位于顶部,则以下内容会将其移至末尾:
[scroll.contentView scrollToPoint:NSMakePoint(0, ((NSView*)scroll.contentView).frame.size.height - scroll.contentSize.height)];
[scroll reflectScrolledClipView: [scroll contentView]];
您可以根据需要修改以上内容。
即使您的代码也可以正常工作,但您需要用相对点代替任何点。
因此,不要将代码放在 for 循环中,而是通过在 xib 上拖动一个按钮来测试它,并在其按钮操作中写入:
NSPoint pointToScrollTo = NSMakePoint ( 100,100 ); // Any point you like.
[[scrollview contentView] scrollToPoint: pointToScrollTo];
[scrollview reflectScrolledClipView: [scrollview contentView]];
现在运行应用程序,将滚动视图的滚动设置到某个随机位置。然后单击按钮并检查滚动是否移动到某处。
如果它有效,那么您的代码就可以了,您只需要相应地设置点。它对我有用。
【讨论】:
我已经按照你说的做了,现在我可以将滚动视图连接到插座,但它仍然不起作用 仍然不能以编程方式滚动。我使用了文档视图,但它仍然不起作用【参考方案4】:我发现如果您使用NSViewController
,您需要在viewWillAppear
方法中执行“滚动点”,而不是在viewWillLoad
中。仅供参考。
【讨论】:
主要是因为NSScollView与documentView链接需要时间,后期最好使用scrollPoint
或者其他滚动方式以上是关于NSScrollview 不以编程方式滚动?的主要内容,如果未能解决你的问题,请参考以下文章
NSScrollView 滚动后在 Xcode 5 中显示问题
带有 CA 图层掩码的 NSScrollView 添加了第二个无用的滚动条