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

与UIView的systemLayoutSizeFitting等效的NSView尺寸计算方法

在NSView中基于约束和目标尺寸计算最优尺寸

NSView原生的fittingSize仅能返回满足约束的最小尺寸,没有直接对应UIView的systemLayoutSizeFitting系列方法的API,但可以通过扩展NSView,利用临时约束结合优先级调整来实现完全对齐的功能。

实现对应UIView的两个方法

下面是NSView的扩展代码,实现与UIView两个systemLayoutSizeFitting方法逻辑一致的功能:

import AppKit

extension NSView {
    // 对应UIView的func systemLayoutSizeFitting(_ targetSize: CGSize) -> CGSize
    func systemLayoutSizeFitting(_ targetSize: CGSize) -> CGSize {
        return systemLayoutSizeFitting(
            targetSize,
            withHorizontalFittingPriority: .defaultHigh,
            verticalFittingPriority: .defaultHigh
        )
    }
    
    // 对应UIView的带优先级参数的systemLayoutSizeFitting方法
    func systemLayoutSizeFitting(
        _ targetSize: CGSize,
        withHorizontalFittingPriority horizontalPriority: NSLayoutConstraint.Priority,
        verticalFittingPriority: NSLayoutConstraint.Priority
    ) -> CGSize {
        var temporaryConstraints = [NSLayoutConstraint]()
        
        // 添加临时宽度约束(仅当目标宽度不是无限大时)
        if targetSize.width != .greatestFiniteMagnitude {
            let widthConstraint = widthAnchor.constraint(equalToConstant: targetSize.width)
            widthConstraint.priority = horizontalPriority
            widthConstraint.isActive = true
            temporaryConstraints.append(widthConstraint)
        }
        
        // 添加临时高度约束(仅当目标高度不是无限大时)
        if targetSize.height != .greatestFiniteMagnitude {
            let heightConstraint = heightAnchor.constraint(equalToConstant: targetSize.height)
            heightConstraint.priority = verticalFittingPriority
            heightConstraint.isActive = true
            temporaryConstraints.append(heightConstraint)
        }
        
        // 计算满足临时约束与原有约束的最优尺寸
        let optimalSize = fittingSize
        
        // 清理临时约束,不影响视图后续布局
        NSLayoutConstraint.deactivate(temporaryConstraints)
        
        return optimalSize
    }
}

逻辑说明

  1. 无优先级参数的方法:默认使用.defaultHigh优先级,和UIView原生方法的默认行为一致,即尽量贴近目标尺寸,同时不打破视图自身的约束。
  2. 带优先级参数的方法:
    • 根据传入的目标尺寸创建临时宽/高约束,约束的优先级由参数指定
    • 激活临时约束后调用fittingSize,此时计算出的尺寸会在原有约束的基础上,尽可能贴合目标尺寸(优先级越高,越倾向于贴近目标尺寸;优先级越低,越优先满足原有约束)
    • 计算完成后立即移除临时约束,避免干扰视图的正常布局流程
  3. 无限大尺寸处理:当目标尺寸的某一维度传入.greatestFiniteMagnitude时,该维度会忽略临时约束,直接返回满足原有约束的最小尺寸,和原生fittingSize的对应维度逻辑一致。

内容的提问来源于stack exchange,提问作者Florian Karimkhan-Zand

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:27:15