Cocoa 使用NSCollectionView显示列表,数据不足布局异常处理

同iOS app 实现横向或纵向列表布局在macOS 中会用到NSCollectionView,不同的是要实现滚动需要指定NSScrollView并将CollectionView对象赋值给ScrollView的documentView。在实际开发中遇到两个问题,一个是 NSScrollView 滚动条一直显示无法隐藏,另外就是 NSCollectionViewFlowLayout 在数据不足一行时,列会居中展示,十分不协调美观。效果如下图:

1、解决滚动条无法隐藏问题(继承后手动隐藏),示例如下:

Swift 复制代码
import Cocoa


//MARK: - CustomScrollView
class CustomScrollView: NSScrollView {
    
    //MARK: - override
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
        
        // Drawing code here.
        self.hiddenScroller()
    }
    
    /// 隐藏滚动条
    public func hiddenScroller(){
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
            self.subviews.forEach { _v in
                if _v is NSScroller {
                    _v.isHidden = true
                }
            }
        }
    }
    
}


//MARK: - CustomCollectionView
class CustomCollectionView : NSCollectionView {
    
    //MARK: - override
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
        
        // Drawing code here.
        self.hiddenScroller()
    }
    
    /// 隐藏滚动条
    public func hiddenScroller(isAsync:Bool = true){
        DispatchQueue.main.async {
            self.enclosingScrollView?.subviews.forEach { _v in
                if _v is NSScroller {
                    _v.isHidden = true
                }
            }
            
            let _hideBlock:()->Void = {
                self.subviews.forEach { _sv in
                    if _sv is NSScrollView {
                        _sv.subviews.forEach { _v in
                            if _v is NSScroller {
                                _v.isHidden = true
                            }
                        }
                    }
                }
            }
            
            if isAsync {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.02) {
                    _hideBlock()
                }
            }
            else{
                _hideBlock()
            }
            
        }
    }
    
}

并在 viewDidUnhide 方法调用

Swift 复制代码
override func viewDidUnhide() {
        super.viewDidUnhide()
        self.scrollView.hiddenScroller()
    }

2、解决NSCollectionViewFlowLayout 数据不足一列布局居中问题,参考如下:

Swift 复制代码
private func createCompositionalLayout() -> NSCollectionViewLayout {
        
        let view_space:CGFloat = (CGRectGetWidth(self.frame) - CGFloat(4) * view_width - CGFloat(2) * view_margin_left_right)/CGFloat(4 - 1)
        
        // Item 大小:每个 item 宽度为容器宽度的 1/4,减去间距
        let itemSize = NSCollectionLayoutSize(
            widthDimension: .fractionalWidth(1.0/4.0),
            heightDimension: .absolute(215)
        )
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        
        // Group:一行显示 4 个 item
        let groupSize = NSCollectionLayoutSize(
            widthDimension: .fractionalWidth(1.0),
            heightDimension: .absolute(215)
        )
        let group = NSCollectionLayoutGroup.horizontal(
            layoutSize: groupSize,
            subitem: item,
            count: 4
        )
        
        // 设置 item 之间的间距(列间距)
        group.interItemSpacing = .fixed(view_space)
        
        // Section
        let section = NSCollectionLayoutSection(group: group)
        section.interGroupSpacing = view_margin_left_right//行间距
        
        // 设置左右间距
        let sideSpacing: CGFloat = view_margin_left_right
        section.contentInsets = NSDirectionalEdgeInsets(
            top: view_margin_left_right,
            leading: sideSpacing,  // 左边距
            bottom: 0,
            trailing: 0// 右边距
        )
        
        return NSCollectionViewCompositionalLayout(section: section)
    }

以上内容就是这些,基本可以解决滚动条没法隐藏及布局异常问题

相关推荐
vi_h2 天前
在 macOS 上通过 Docker 安装并运行 Ollama(详细可执行教程)
macos·docker·ollama
TT_Close2 天前
【Flutter×鸿蒙】FVM 不认鸿蒙 SDK?4步手动塞进去
flutter·swift·harmonyos
张江2 天前
Swift Concurrency学习
swift
东坡肘子5 天前
OpenClaw 不错,但我好像没有那么需要 -- 肘子的 Swift 周报 #125
人工智能·swiftui·swift
pe7er7 天前
macOS 应用无法打开(权限问题)解决方案
macos·mac
harmful_sheep10 天前
mac生效的终端查看
macos
Swift社区10 天前
LeetCode 391 完美矩形 - Swift 题解
算法·leetcode·swift
iOS门童10 天前
macOS 应用"已损坏"无法打开?一文搞懂 Gatekeeper 与解决方案
macos
NPE~10 天前
[工具分享]Maccy —— 优雅的 macOS 剪贴板历史管理工具
macos·教程·工具·实用工具
差不多程序员10 天前
Mac安装OpenClaw-cn保姆级教程
macos