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)
    }

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

相关推荐
东坡肘子15 小时前
当每一次写入都有了新价格 -- 肘子的 Swift 周报 #144
人工智能·swiftui·swift
zzb158015 小时前
Zed 配置 Swift / iOS 开发
开发语言·ios·swift
全堆鸿蒙1 天前
25 数据库设计与表结构规划:5 张表的设计思路
数据库·华为·cocoa·harmonyos
colman wang1 天前
Git指令(Mac)
git·macos
Geek-Chow2 天前
Mobile App Certificate Pinning: Underlying Principle and a Swift Example
开发语言·ios·swift·安全架构
酷虎软件2 天前
分享链接+视频音频文案提取 API 接口文档
ide·macos·xcode
Hyyy2 天前
为什么 macOS 应用一换 Bundle ID,之前授予的权限就全失效了?
macos·electron
p似笑非笑2 天前
实战验证——把 SDK 塞进一个 macOS 原生 Agent 应用
macos
p似笑非笑2 天前
在Mac上完美配置VSCode的C/C++开发环境(GCC/G++详细教程)
c语言·vscode·macos
韦胖漫谈IT3 天前
Apple M3 Max 与 Apple M5 Max 对比:本地算力的新旧王者之争
网络·人工智能·macos·transformer