Skip to content

Commit

Permalink
feat: 馃幐 [JIRA: 2219] List picker with single selection
Browse files Browse the repository at this point in the history
Support single selection and allow empty filter condition
  • Loading branch information
xiaoyu0722 committed Nov 17, 2022
1 parent 60689c9 commit a2299d8
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 24 deletions.
4 changes: 4 additions & 0 deletions Apps/Examples/Examples.xcodeproj/project.pbxproj
Expand Up @@ -79,6 +79,7 @@
9996CD03262FFEBE001B99AE /* EULA2.html in Resources */ = {isa = PBXBuildFile; fileRef = 9996CD02262FFEBD001B99AE /* EULA2.html */; };
99B6EF8C2672224D00515E8E /* UserConsentSample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99B6EF8B2672224C00515E8E /* UserConsentSample.swift */; };
AB988B102631270300483D87 /* DataTableExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB988B0F2631270300483D87 /* DataTableExample.swift */; };
B141D6BB29261F9E008A8BD6 /* SearchableListViewExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = B141D6BA29261F9E008A8BD6 /* SearchableListViewExample.swift */; };
B80DA9BA260BBF8600C0B2E9 /* SingleActionProfiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = B80DA9B9260BBF8600C0B2E9 /* SingleActionProfiles.swift */; };
B80DA9BC260BED9400C0B2E9 /* SingleActionCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B80DA9BB260BED9400C0B2E9 /* SingleActionCollectionView.swift */; };
B80DA9BE260C1CC200C0B2E9 /* ListDataProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B80DA9BD260C1CC200C0B2E9 /* ListDataProtocol.swift */; };
Expand Down Expand Up @@ -220,6 +221,7 @@
9996CD02262FFEBD001B99AE /* EULA2.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = EULA2.html; sourceTree = "<group>"; };
99B6EF8B2672224C00515E8E /* UserConsentSample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserConsentSample.swift; sourceTree = "<group>"; };
AB988B0F2631270300483D87 /* DataTableExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataTableExample.swift; sourceTree = "<group>"; };
B141D6BA29261F9E008A8BD6 /* SearchableListViewExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchableListViewExample.swift; sourceTree = "<group>"; };
B80DA9B9260BBF8600C0B2E9 /* SingleActionProfiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleActionProfiles.swift; sourceTree = "<group>"; };
B80DA9BB260BED9400C0B2E9 /* SingleActionCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleActionCollectionView.swift; sourceTree = "<group>"; };
B80DA9BD260C1CC200C0B2E9 /* ListDataProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDataProtocol.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -278,6 +280,7 @@
isa = PBXGroup;
children = (
1F3C92F025DF12C100A99A07 /* ListPicker.swift */,
B141D6BA29261F9E008A8BD6 /* SearchableListViewExample.swift */,
);
path = FormCells;
sourceTree = "<group>";
Expand Down Expand Up @@ -756,6 +759,7 @@
69B2B5D9268A333C009AC6B3 /* KPIProgressViewExample.swift in Sources */,
B80DA9C72612A54E00C0B2E9 /* WelcomeScreenSample.swift in Sources */,
8A5579D724C1293C0098003A /* SettingsCategoryAxis.swift in Sources */,
B141D6BB29261F9E008A8BD6 /* SearchableListViewExample.swift in Sources */,
975CB76B256C5A7400DB7A15 /* SignatureCaptureViewExample.swift in Sources */,
8AD9DFB125D49967007448EC /* ContactItemStateAndDataBindingExample.swift in Sources */,
B86F02A82679835F0049DDA7 /* ObjectItemInitExamples.swift in Sources */,
Expand Down
Expand Up @@ -2,7 +2,7 @@ import FioriSwiftUICore
import Foundation
import SwiftUI

private enum ListPickerItemDataModel {
enum ListPickerItemDataModel {
struct Framework: Identifiable {
var id = UUID()
let name: String
Expand Down Expand Up @@ -52,7 +52,7 @@ struct ListPickerItemExample: View {
case objectItem
case stringItem
case searchable

case searchableListView
var id: Self { self }
}

Expand Down Expand Up @@ -84,7 +84,12 @@ struct ListPickerItemExample: View {
case .searchable:
NavigationLink(
destination: ListPickerItemWithSearchExample()) {
Text("Searchable")
Text("Searchable List Picker Item")
}
case .searchableListView:
NavigationLink(
destination: SearchableListViewExample()) {
Text("Searchable List View")
}
}
}
Expand Down
@@ -0,0 +1,139 @@
import FioriSwiftUICore
import SwiftUI

struct SearchableListViewExample: View {
@Environment(\.presentationMode) var presentationMode

private let model = ListPickerItemDataModel.data

@State var selection1: Set<UUID> = []
@State var selection2: Set<UUID> = [ListPickerItemDataModel.data.last?.id ?? UUID()]
@State var selection3: Set<UUID> = []
@State var selection4: Set<UUID> = []
@State var selection5: Set<UUID> = []

@State var presentingModal: Bool = false

public var body: some View {
VStack {
HStack {
Text("empty first")
Spacer()
NavigationLink {
pickerView($selection1)
} label: {
let str = selectedValues(Array(selection1))
Text(str.isEmpty ? "pick one" : str)
.frame(minWidth: 100, minHeight: 40)
.background(Color.black.opacity(0.1))
}
}

HStack {
Text("with pre-selection")
Spacer()
NavigationLink {
pickerView($selection2)
} label: {
let str = selectedValues(Array(selection2))
Text(str)
.frame(minWidth: 100, minHeight: 40)
.background(Color.black.opacity(0.1))
}
}

HStack {
Text("allow multi-selections")
Spacer()
NavigationLink {
pickerView($selection3, true)
} label: {
let str = selectedValues(Array(selection3))
Text(str)
.frame(minWidth: 100, minHeight: 40)
.background(Color.black.opacity(0.1))
}
}

HStack {
Text("empty search filter")
Spacer()
NavigationLink {
pickerView($selection4, false, true)
} label: {
let str = selectedValues(Array(selection4))
Text(str)
.frame(minWidth: 100, minHeight: 40)
.background(Color.black.opacity(0.1))
}
}

HStack {
Text("sheet present")
Spacer()
let str = selectedValues(Array(selection5))
Text(str)
.frame(minWidth: 100, minHeight: 40)
.background(Color.black.opacity(0.1))
.onTapGesture {
presentingModal = true
}
.sheet(isPresented: $presentingModal) {
NavigationView {
pickerView($selection5)
}
}
}

Spacer()
}
.padding()
.navigationBarTitle(Text("SeachableListViewExample"))
}

func selectedValues(_ selection: [UUID]) -> String {
let str = selection.compactMap { uuid in
if let framework = ListPickerItemDataModel.getFramwork(with: uuid) {
return framework.name
}
return nil
}.joined(separator: ", ")
return str
}

func pickerView(_ selection: Binding<Set<UUID>>, _ allowsMultipleSelection: Bool = false, _ emptySearch: Bool = false) -> some View {
if #available(iOS 15.0, *) {
let filter: ((ListPickerItemDataModel.Framework, String) -> Bool) = { f, s in
if s.count > 0 {
return f.name.localizedCaseInsensitiveContains(s)
} else {
return true
}
}
return SearchableListView(data: model, id: \.id, children: \.children,
selection: selection,
allowsMultipleSelection: allowsMultipleSelection,
searchFilter: emptySearch ? nil : filter) { framework in
ObjectItem {
Text(framework.name)
} descriptionText: {
Text("description")
} status: {
Image(systemName: "sun.min")
} detailImage: {
Image(systemName: "mail")
}
}
} else {
return EmptyView()
}
}
}

struct SearchableListViewExample_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
SearchableListViewExample()
}
}
}

0 comments on commit a2299d8

Please sign in to comment.