You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSScrollView嵌套NSStackView后无法滚动的问题求助

NSScrollView嵌套NSStackView后无法滚动的问题求助

我现在正在学习Swift和相关框架,想实现一个带滚动效果的组合布局:顶部是一个NSStackView,下方是展示图片的网格NSCollectionView,整体放在NSScrollView里支持垂直滚动。

不过我遇到了一个卡了很久的小问题:当直接把NSCollectionView设置为scrollView.documentView时,滚动完全正常;但如果把NSCollectionView和顶部的StackView一起放进另一个垂直方向的NSStackView,再将这个外层StackView设为scrollView.documentView,就完全没法滚动了😭。


可以正常滚动的案例

代码实现

override func viewDidLoad() {
    super.viewDidLoad()
    
    scrollView = NSScrollView(frame: .zero)
    scrollView.hasVerticalScroller = true
    scrollView.hasHorizontalScroller = false
    scrollView.scrollerStyle = .overlay
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    
    view.addSubview(scrollView)
    vStack = NSStackView(frame: .zero)
    vStack.orientation = .vertical
    vStack.spacing = 12 * 2
    vStack.translatesAutoresizingMaskIntoConstraints = false
    
    let hStack = NSStackView()
    hStack.orientation = .horizontal
    hStack.spacing = 12
    hStack.translatesAutoresizingMaskIntoConstraints = false

    let label1 = NSTextField(labelWithString: "Collection")
    
    hStack.addArrangedSubview(label1)
    
    let layout = PinterestLayout()
    layout.delegate = self
    
    collectionView = NSCollectionView(frame: .zero)
    collectionView.collectionViewLayout = layout
    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView
        .register(
            ArtCardCell.self,
            forItemWithIdentifier: NSUserInterfaceItemIdentifier("ArtCardCell")
        )
    collectionView.backgroundColors = [.BG]
    collectionView.translatesAutoresizingMaskIntoConstraints = false
    
//    vStack.addArrangedSubview(hStack)
//    vStack.addArrangedSubview(collectionView)
    
    scrollView.documentView = collectionView

    NSLayoutConstraint.activate([
               scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
               scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
               scrollView.topAnchor.constraint(equalTo: view.topAnchor),
               scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
               
//               vStack.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
//               vStack.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
//               vStack.topAnchor.constraint(equalTo: scrollView.topAnchor),
//               vStack.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
//               vStack.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
               
               collectionView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
               
//               vStack.arrangedSubviews[0].leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 12),
//               vStack.arrangedSubviews[0].trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -12),
//               vStack.arrangedSubviews[0].topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 80)
           ])
    
    collectionView.postsBoundsChangedNotifications = true
    NotificationCenter.default.addObserver(self, selector: #selector(didScroll(_:)),
                                           name: NSView.boundsDidChangeNotification,
                                           object: collectionView.enclosingScrollView?.contentView
    )
}

此时各视图的高度信息

collectionView   height: 3549.0
ScrollView       height: 628.0
StackView        height: --

无法滚动的案例

代码实现

override func viewDidLoad() {
    super.viewDidLoad()
    
    scrollView = NSScrollView(frame: .zero)
    scrollView.hasVerticalScroller = true
    scrollView.hasHorizontalScroller = false
    scrollView.scrollerStyle = .overlay
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    
    view.addSubview(scrollView)
    vStack = NSStackView(frame: .zero)
    vStack.orientation = .vertical
    vStack.spacing = 12 * 2
    vStack.translatesAutoresizingMaskIntoConstraints = false
    
    let hStack = NSStackView()
    hStack.orientation = .horizontal
    hStack.spacing = 12
    hStack.translatesAutoresizingMaskIntoConstraints = false

    let label1 = NSTextField(labelWithString: "Collection")
    
    hStack.addArrangedSubview(label1)
    
    let layout = PinterestLayout()
    layout.delegate = self
    
    collectionView = NSCollectionView(frame: .zero)
    collectionView.collectionViewLayout = layout
    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView
        .register(
            ArtCardCell.self,
            forItemWithIdentifier: NSUserInterfaceItemIdentifier("ArtCardCell")
        )
    collectionView.backgroundColors = [.BG]
    collectionView.translatesAutoresizingMaskIntoConstraints = false
    
    vStack.addArrangedSubview(hStack)
    vStack.addArrangedSubview(collectionView)
    
    scrollView.documentView = vStack

    NSLayoutConstraint.activate([
               scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
               scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
               scrollView.topAnchor.constraint(equalTo: view.topAnchor),
               scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
               
               vStack.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
               vStack.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
               vStack.topAnchor.constraint(equalTo: scrollView.topAnchor),
               vStack.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
               vStack.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
               
               collectionView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
               
               vStack.arrangedSubviews[0].leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 12),
               vStack.arrangedSubviews[0].trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -12),
               vStack.arrangedSubviews[0].topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 80)
           ])
}

此时各视图的高度信息

collectionView   height: 508.0
ScrollView       height: 628.0
StackView        height: 628.0

如果有人能给我一些相关的文档参考,或者直接的解决思路,我真的非常感激!


备注:内容来源于stack exchange,提问作者unindiendanslaville

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 03:08:06