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

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

相关推荐
黑科技iOS上架10 小时前
Cocos应用App Store4.3被拒怎么自查
macos·ios·objective-c·cocoa·审核·ios混淆·cocos混淆
典典分享指南12 小时前
AI 配图的排版规范
macos·docker·github·vim·visual studio
东坡肘子15 小时前
iPhone Duo 带来的机遇与挑战 -- 肘子的 Swift 周报 #153
人工智能·swiftui·swift
YJlio1 天前
锤子助手第012个开关:启用朋友圈视频进度条的位置、验证方法与播放交互边界
objective-c·视频播放·功能验证·锤子助手·朋友圈视频进度条·ios微信插件·交互测试
:-)1 天前
修改mac电脑用户名
macos
Είναι η κοπέλα1 天前
本地大模型部署完全指南:Ollama / vLLM / llama.cpp / MLX 四大引擎横评与选型实战
macos·llama·vllm
那年窗外下的雪.2 天前
AIDC 学习日志|第 25 天|设备输出反推、MAC Flapping 与 EAD 撤销
前端·网络·git·学习·macos
星辰即远方2 天前
RunLoop初步了解
macos·objective-c·cocoa
代码的小搬运工2 天前
Runloop
macos·objective-c·cocoa