Last active
April 7, 2020 18:11
-
-
Save ccwasden/a822b48238498dd8c8dddaa64238c5ac to your computer and use it in GitHub Desktop.
Multiselect using a custom property wrapper - Modified from child view through a Binding
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Author: Chase Wasden | |
// Website: https://gist.github.com/ccwasden | |
// Licensed under MIT license https://opensource.org/licenses/MIT | |
// | |
import SwiftUI | |
struct Fruit: Identifiable { | |
let name: String | |
var isSelected: Bool | |
var id: String { name } | |
} | |
struct FruitList: View { | |
@BindableArray var fruits = [ | |
Fruit(name: "Apple", isSelected: false), | |
Fruit(name: "Banana", isSelected: true), | |
Fruit(name: "Kumquat", isSelected: false), | |
] | |
var body: some View { | |
VStack { | |
Text("Select Fruits (\(fruits.filter { $0.isSelected }.count))") | |
List($fruits) { (fruit: Binding<Fruit>) in | |
FruitRow(fruit: fruit) | |
} | |
} | |
} | |
struct FruitRow: View { | |
@Binding var fruit: Fruit | |
var body: some View { | |
Button(action: { self.fruit.isSelected.toggle() }) { | |
HStack { | |
Text(fruit.isSelected ? "☑" : "☐") | |
Text(fruit.name) | |
} | |
} | |
} | |
} | |
} | |
// ----------- The Reusable Magic ----------- // | |
extension Binding: Identifiable where Value: Identifiable { | |
public var id: Value.ID { | |
return wrappedValue.id | |
} | |
} | |
@propertyWrapper | |
struct BindableArray<Value> : DynamicProperty { | |
@State var storage: [Value] | |
init(wrappedValue value: [Value]) { | |
self._storage = State(initialValue: value) | |
} | |
public var wrappedValue: [Value] { | |
get { storage } | |
nonmutating set { storage = newValue } | |
} | |
public var projectedValue: [Binding<Value>] { | |
var bindings = [Binding<Value>]() | |
for (i, item) in storage.enumerated() { | |
bindings.append(Binding( | |
get: { item }, | |
set: { self.wrappedValue[i] = $0 } | |
)) | |
} | |
return bindings | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment