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

Swift迁移代码报错:Dictionary.Values无法用+合并的解决咨询

Fixing "Binary operator '+' cannot be applied to two 'Dictionary.Values' operands" in Swift

Hey there! Let's tackle that error you're hitting when merging dictionary values. The root issue is simple: Dictionary.Values is a specialized collection type, not an array, so Swift doesn't let you use the + operator directly on it.

The Problem with Your Current Code

In these lines, you're trying to add Dictionary.Values instances together, which isn't allowed:

var result = cellAttrDict.values + supplHeaderAttrDict.values
result = result + supplFooterAttrDict.values
result = result + decorAttrDict.values

The Solution: Convert to Arrays First

All you need to do is convert each Dictionary.Values collection to an array using Array(), then you can use the + operator (or += for appending) as expected. Here's how to update those lines:

// Convert each dictionary's values to arrays before merging
var result = Array(cellAttrDict.values) + Array(supplHeaderAttrDict.values)
result += Array(supplFooterAttrDict.values)
result += Array(decorAttrDict.values)

Or for a more concise, readable approach:

let result = Array(cellAttrDict.values)
    + Array(supplHeaderAttrDict.values)
    + Array(supplFooterAttrDict.values)
    + Array(decorAttrDict.values)

Bonus: Clean Up Optional Handling (Optional)

While we're at it, you can make your code safer by replacing forced unwraps (as!) with optional binding to avoid runtime crashes. For example, instead of:

if rect.intersects(unionRects[i] as! CGRect) {

You can write:

guard let unionRect = unionRects[i] as? CGRect else { continue }
if rect.intersects(unionRect) {

This makes your code more robust if unionRects ever contains non-CGRect values.

Full Updated Method

Here's your complete method with the fix applied, plus some type-safety improvements:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    var begin = 0
    var end = unionRects.count
    var cellAttrDict: [AnyHashable : UICollectionViewLayoutAttributes] = [:]
    var supplHeaderAttrDict: [AnyHashable : UICollectionViewLayoutAttributes] = [:]
    var supplFooterAttrDict: [AnyHashable : UICollectionViewLayoutAttributes] = [:]
    var decorAttrDict: [AnyHashable : UICollectionViewLayoutAttributes] = [:]
    
    for i in 0..<unionRects.count {
        guard let unionRect = unionRects[i] as? CGRect else { continue }
        if rect.intersects(unionRect) {
            begin = i * unionSize
            break
        }
    }
    
    var i = unionRects.count - 1
    while i >= 0 {
        guard let unionRect = unionRects[i] as? CGRect else {
            i -= 1
            continue
        }
        if rect.intersects(unionRect) {
            end = min((i + 1) * unionSize, allItemAttributes.count)
            break
        }
        i -= 1
    }
    
    for i in begin..<end {
        guard let attr = allItemAttributes[i] as? UICollectionViewLayoutAttributes else { continue }
        guard rect.intersects(attr.frame) else { continue }
        
        switch attr.representedElementCategory {
        case .supplementaryView:
            if attr.representedElementKind == CHTCollectionElementKindSectionHeader {
                supplHeaderAttrDict[attr.indexPath] = attr
            } else if attr.representedElementKind == CHTCollectionElementKindSectionFooter {
                supplFooterAttrDict[attr.indexPath] = attr
            }
        case .decorationView:
            decorAttrDict[attr.indexPath] = attr
        case .cell:
            cellAttrDict[attr.indexPath] = attr
        @unknown default:
            break
        }
    }
    
    // Fixed value merging by converting to arrays
    let result = Array(cellAttrDict.values)
        + Array(supplHeaderAttrDict.values)
        + Array(supplFooterAttrDict.values)
        + Array(decorAttrDict.values)
    
    return result
}

I also updated the dictionary types to explicitly use UICollectionViewLayoutAttributes instead of Any—this makes your code more type-safe and removes the need for the final as? cast when returning.

内容的提问来源于stack exchange,提问作者uma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:56:40