📱

[SwiftUI] AnyViewの使用を避ける

2021/04/30に公開

シチュエーション

Viewにいろいろなものをおきたい(TextとかImageとか)だけど、プロパティとしては一つにしておきたい。

やり方

planA: AnyViewを使う

メリット デメリット
使い勝手がいい コードが冗長になる

planB: Genericsを使う

メリット デメリット
使い勝手いいし、コードもシンプル 特になさそう

サンプルコード

import SwiftUInn

struct DrawingView: View {
    @State private var elements: [DrawingElement] = [
        DrawingElement(rect: CGRect(x: 0, y: 0, width: 100, height: 100), elementView: Text("aaa")),
        DrawingElement(rect: CGRect(x: 100, y: 100, width: 100, height: 100), elementView: Text("bbb")),
        DrawingElement(rect: CGRect(x: 200, y: 200, width: 100, height: 100), elementView: Text("ccc"))
    ]
    
    var body: some View {
        ZStack {
            ForEach(elements, id: \.self) { element in
                element.elementView
                    .frame(width: element.rect.width, height: element.rect.height)
                    .background(Color.red)
                    .position(x: element.rect.midX, y: element.rect.midY)
            }
        }
    }
}

struct DrawingView_Previews: PreviewProvider {
    static var previews: some View {
        DrawingView()
    }
}

struct DrawingElement<ElementView: View> {
    let uuid: String = UUID().uuidString
    let rect: CGRect
    let elementView: ElementView
}

extension DrawingElement: Hashable {
    static func == (lhs: DrawingElement, rhs: DrawingElement) -> Bool {
        return lhs.uuid == rhs.uuid
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(uuid)
    }
}

参考記事: https://www.swiftbysundell.com/articles/avoiding-anyview-in-swiftui/

Discussion