Cocoa NSScrollView封装NSCollectionView在调整大小时始终向后滚动

Cocoa NSScrollView封装NSCollectionView在调整大小时始终向后滚动,cocoa,nsscrollview,nscollectionview,Cocoa,Nsscrollview,Nscollectionview,程序将打开一个窗口,其中包含包含1000个项目的集合视图。如果我向下滚动一点,然后在任何方向调整窗口大小,滚动视图将立即跳回顶部 该应用程序是在没有故事板或XIB的情况下构建的通过Interface Builder构建类似应用程序时,不会出现此问题。似乎缺少一些东西,Interface Builder默认配置了一些东西。我正在macOS 11.2.3上用Xcode 12.4测试这一点。有什么想法吗 为了便于复制,我将所有内容打包在一个文件main.swift: 导入可可粉 让delegate=A

程序将打开一个窗口,其中包含包含1000个项目的集合视图。如果我向下滚动一点,然后在任何方向调整窗口大小,滚动视图将立即跳回顶部

该应用程序是在没有故事板或XIB的情况下构建的通过Interface Builder构建类似应用程序时,不会出现此问题。似乎缺少一些东西,Interface Builder默认配置了一些东西。我正在macOS 11.2.3上用Xcode 12.4测试这一点。有什么想法吗

为了便于复制,我将所有内容打包在一个文件
main.swift

导入可可粉
让delegate=AppDelegate()
NSApplication.shared.delegate=委托
_=NSApplicationMain(CommandLine.argc、CommandLine.gv)
类AppDelegate:NSObject、NSApplicationDelegate、NSSplitViewDelegate{
变量窗口:NSWindow?
var数据源:CollectionViewDataSource?
var collectionView:NSCollectionView?
func ApplicationIDFinishLaunching(通知:通知){
让屏幕大小=NSScreen.main?frame.size??NSSize(宽:1920,高:1080)
window=NSWindow(contentRect:NSMakeRect(screenSize.width/4,screenSize.height/4,screenSize.width/2,screenSize.height/2),
样式掩码:[.minimable、.closable、.resize、.titled],
备份:。缓冲,
延迟:假)
车窗?.MakeKeyandDerfront(无)
如果let view=window?.contentView{
collectionView=NSCollectionView(帧:NSZeroRect)
dataSource=CollectionViewDataSource()
让scrollView=NSScrollView(帧:NSZeroRect)
view.addSubview(滚动视图)
scrollView.TranslatesAutoResizezingMaskintoConstraints=false
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(相等于:view.leadingAnchor),
scrollView.topAnchor.constraint(equalTo:view.topAnchor),
scrollView.trailingAnchor.constraint(等式:view.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo:view.bottomAnchor),
])
scrollView.documentView=collectionView
collectionView?.collectionViewLayout=NSCollectionViewFlowLayout()
collectionView?.register(CollectionViewItem.self,forItemWithIdentifier:NSUserInterfaceItemIdentifier(原始值:“CollectionViewItem”))
collectionView?.dataSource=数据源
}
}
}
类CollectionViewDataSource:NSObject,NSCollectionViewDataSource{
func numberOfSections(在collectionView:NSCollectionView中)->Int{
返回1
}
func collectionView(collectionView:NSCollectionView,numberOfItemsInSection:Int)->Int{
返回1000
}
func collectionView(collectionView:NSCollectionView,itemForRepresentedObjectAt indexPath:indexPath)->NSCollectionViewItem{
将i=collectionView.makeItem(标识符为:NSUserInterfaceItemIdentifier(rawValue:“CollectionViewItem”),for:indexPath)设为!CollectionViewItem
i、 view.wantsLayer=true
i、 view.layer?.backgroundColor=NSColor.init(颜色空间:NSColorSpace.deviceRGB,色调:CGFloat(Float.random)(in:0..NSView{
fatalError(“未实施”)
}
}
类CollectionViewItem:NSCollectionViewItem{
重写func loadView(){
self.view=NSView(帧:NSZeroRect)
}
}

故事板中集合视图的源代码:

<collectionView id="yh4-in-fLt">
    <rect key="frame" x="0.0" y="0.0" width="480" height="158"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
    <collectionViewFlowLayout key="collectionViewLayout" minimumInteritemSpacing="10" minimumLineSpacing="10" id="TGK-mX-O4r">
        <size key="itemSize" width="50" height="50"/>
    </collectionViewFlowLayout>
    <color key="primaryBackgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</collectionView>

忽略帧更改通知似乎可以做到这一点

添加自定义的
NSClipView
作为
NSScrollView
的内容视图,如下所示:

scrollView.contentView=ClipViewIgnoringFrameChange()
其中
ClipViewIgnoringFrameChange()
的定义如下:

class ClipViewWignoringFrameChange:NSClipView{
重写func viewFrameChanged(uNotification:notification){}
}

谢谢您的回答。不过,对于问题中发布的代码,它不起作用。我通过使剪辑视图忽略帧更改,成功地使它起作用。
collectionView.autoresizingMask = [.width]