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

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

相关推荐
小天源2 小时前
智叟云集系统:便携部署、MAC 授权与交付排障
macos
Joy T8 小时前
voice-dump-to-todo:把混乱的语音整理成可执行待办,一个实用的 Agent Skill
ide·macos·语音识别·xcode·任务管理·自研skill
szp200513 小时前
中文字幕烧进视频后整片空白:CoreText 低报行高,导出照样成功
ios·swift
JPower_mr.g15 小时前
SmartCall v1.0.9 发布:智能体知识库上线,让 AI 客服先查资料再回答
java·ide·人工智能·macos·架构·开源·xcode
轻口味17 小时前
启元无真机二开实战:先在Mac上养一台Q1——官方URDF到MuJoCo数字孪生的完整链
macos·具身智能·mujoco·启元机器人
2601_967979121 天前
AccessControl 5.4 macOS Python 3.9 版本安装包
python·macos·security·accesscontrol·permissions
2501_915106321 天前
iOS 单元测试怎么跑?用 KXApp 在 VS Code 里跑 XCTest 和 Swift Testing
ide·vscode·ios·单元测试·个人开发·swift·敏捷流程
东坡肘子1 天前
当应用不再属于特定操作系统 -- 肘子的 Swift 周报 #159
人工智能·swiftui·swift
EVE จุ๊บ2 天前
Mac安装Playwright
macos
全栈探索者2 天前
出图模型怎么选?同一只猫的四场实测:Z-Image、Qwen-Image 2.1、SD1.5 三维对决
人工智能·macos·aigc·stablediffusion·comfyui