Skip to content

Commit

Permalink
Merge pull request #6 from MrAsterisco/4-layout-issues-in-list
Browse files Browse the repository at this point in the history
Fix ComboPicker in List
  • Loading branch information
MrAsterisco committed Jul 4, 2022
2 parents b502429 + 699d54d commit f0bb696
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
objects = {

/* Begin PBXBuildFile section */
FA190ACF2871E4D400C0AC2D /* BasicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA190ACE2871E4D400C0AC2D /* BasicView.swift */; };
FA190AD02871E4D400C0AC2D /* BasicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA190ACE2871E4D400C0AC2D /* BasicView.swift */; };
FA190AD22871E55B00C0AC2D /* ListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA190AD12871E55A00C0AC2D /* ListView.swift */; };
FA190AD32871E55B00C0AC2D /* ListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA190AD12871E55A00C0AC2D /* ListView.swift */; };
FA3DD73328707EDC00F37155 /* ComboPicker in Frameworks */ = {isa = PBXBuildFile; productRef = FA3DD73228707EDC00F37155 /* ComboPicker */; };
FA614FE7286CDB8F00ADEE20 /* ComboPickerExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA614FE6286CDB8F00ADEE20 /* ComboPickerExampleApp.swift */; };
FA614FE9286CDB8F00ADEE20 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA614FE8286CDB8F00ADEE20 /* ContentView.swift */; };
Expand Down Expand Up @@ -51,6 +55,8 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
FA190ACE2871E4D400C0AC2D /* BasicView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicView.swift; sourceTree = "<group>"; };
FA190AD12871E55A00C0AC2D /* ListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListView.swift; sourceTree = "<group>"; };
FA3DD73128707EB900F37155 /* ComboPicker */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = ComboPicker; path = ../..; sourceTree = "<group>"; };
FA614FE3286CDB8F00ADEE20 /* ComboPickerExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ComboPickerExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
FA614FE6286CDB8F00ADEE20 /* ComboPickerExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComboPickerExampleApp.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -123,6 +129,8 @@
FA614FF5286CDBA700ADEE20 /* Data */,
FA614FE6286CDB8F00ADEE20 /* ComboPickerExampleApp.swift */,
FA614FE8286CDB8F00ADEE20 /* ContentView.swift */,
FA190ACE2871E4D400C0AC2D /* BasicView.swift */,
FA190AD12871E55A00C0AC2D /* ListView.swift */,
FA614FEA286CDB9000ADEE20 /* Assets.xcassets */,
FA614FEC286CDB9000ADEE20 /* ComboPickerExample.entitlements */,
FA614FED286CDB9000ADEE20 /* Preview Content */,
Expand Down Expand Up @@ -310,6 +318,8 @@
FA614FE9286CDB8F00ADEE20 /* ContentView.swift in Sources */,
FA614FE7286CDB8F00ADEE20 /* ComboPickerExampleApp.swift in Sources */,
FA614FF9286CDBB100ADEE20 /* ExampleModel+StaticData.swift in Sources */,
FA190AD22871E55B00C0AC2D /* ListView.swift in Sources */,
FA190ACF2871E4D400C0AC2D /* BasicView.swift in Sources */,
FADCE652287191B1004BC0CB /* ExampleModelFormatter.swift in Sources */,
FA614FF7286CDBAC00ADEE20 /* ExampleModel.swift in Sources */,
);
Expand All @@ -322,6 +332,8 @@
FA615019286CDDB900ADEE20 /* ContentView.swift in Sources */,
FA61500A286CDD6900ADEE20 /* ComboPickerWatchApp.swift in Sources */,
FA61501B286CDDD300ADEE20 /* ExampleModel+StaticData.swift in Sources */,
FA190AD32871E55B00C0AC2D /* ListView.swift in Sources */,
FA190AD02871E4D400C0AC2D /* BasicView.swift in Sources */,
FADCE65328719284004BC0CB /* ExampleModelFormatter.swift in Sources */,
FA61501A286CDDCF00ADEE20 /* ExampleModel.swift in Sources */,
);
Expand Down
51 changes: 51 additions & 0 deletions Examples/ComboPickerExample/ComboPickerExample/BasicView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// BasicView.swift
// ComboPickerExample
//
// Created by Alessio Moiso on 03.07.22.
//

import SwiftUI
import ComboPicker

#if os(watchOS) || os(tvOS)
typealias Stack = VStack
#else
typealias Stack = HStack
#endif

struct BasicView: View {
@State private var content = ExampleModel.data

@State private var selection = ExampleModel.data.first!.value
@State private var otherSelection = ExampleModel.data.last!.value

var body: some View {
Stack {
ComboPicker(
title: "Pick a number",
manualTitle: "Custom...",
valueFormatter: ExampleModelFormatter(),
content: $content,
value: $selection
)
.keyboardType(.numberPad)

ComboPicker(
title: "Pick another number",
manualTitle: "Custom...",
valueFormatter: ExampleModelFormatter(),
content: $content,
value: $otherSelection
)
.keyboardType(.numberPad)
}
.padding()
}
}

struct BasicView_Previews: PreviewProvider {
static var previews: some View {
BasicView()
}
}
37 changes: 9 additions & 28 deletions Examples/ComboPickerExample/ComboPickerExample/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,18 @@
import SwiftUI
import ComboPicker

#if os(watchOS) || os(tvOS)
typealias Stack = VStack
#else
typealias Stack = HStack
#endif

struct ContentView: View {
@State private var content = ExampleModel.data

@State private var selection = ExampleModel.data.first!.value
@State private var otherSelection = ExampleModel.data.last!.value

var body: some View {
Stack {
ComboPicker(
title: "Pick a number",
manualTitle: "Custom...",
valueFormatter: ExampleModelFormatter(),
content: $content,
value: $selection
)
.keyboardType(.numberPad)
TabView {
BasicView()
.tabItem {
Text("Basic")
}

ComboPicker(
title: "Pick another number",
manualTitle: "Custom...",
valueFormatter: ExampleModelFormatter(),
content: $content,
value: $otherSelection
)
.keyboardType(.numberPad)
ListView()
.tabItem {
Text("List")
}
}
.padding()
}
Expand Down
50 changes: 50 additions & 0 deletions Examples/ComboPickerExample/ComboPickerExample/ListView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// ListView.swift
// ComboPickerExample
//
// Created by Alessio Moiso on 03.07.22.
//

import SwiftUI
import ComboPicker

struct ListView: View {
@State private var content = ExampleModel.data

@State private var selection = ExampleModel.data.first!.value
@State private var otherSelection = ExampleModel.data.last!.value

var body: some View {
List {
ComboPicker(
title: "Pick a number",
manualTitle: "Custom...",
valueFormatter: ExampleModelFormatter(),
content: $content,
value: $selection
)

.keyboardType(.numberPad)
.padding()

ComboPicker(
title: "Pick another number",
manualTitle: "Custom...",
valueFormatter: ExampleModelFormatter(),
content: $content,
value: $otherSelection
)
.keyboardType(.numberPad)
.padding()
}
#if os(iOS)
.listStyle(.insetGrouped)
#endif
}
}

struct ListView_Previews: PreviewProvider {
static var previews: some View {
ListView()
}
}
2 changes: 1 addition & 1 deletion Sources/ComboPicker/ComboPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ public extension ComboPicker {

private extension ComboPicker {
func change(to mode: ComboPickerMode) {
focus = mode
withAnimation {
self.mode = mode
focus = mode
}
}
}
13 changes: 13 additions & 0 deletions Sources/ComboPicker/Constants/Constants.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// File.swift
//
//
// Created by Alessio Moiso on 04.07.22.
//

import Foundation

enum Constants {
static let pickerHeight: CGFloat = 30
static let pickerPadding: CGFloat = 15
}
47 changes: 29 additions & 18 deletions Sources/ComboPicker/Views/ManualInput.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import SwiftUI
struct ManualInput: View {
private let title: String
private let keyboardType: KeyboardType
private let action: () -> ()

@Binding private var value: String
@FocusState private var focus: ComboPickerMode?

let action: () -> ()

init(
title: String = "",
keyboardType: KeyboardType = .default,
Expand All @@ -32,23 +31,25 @@ struct ManualInput: View {

var body: some View {
#if os(iOS) || os(macOS)
TextField(title, text: $value)
#if !os(macOS)
.keyboardType(keyboardType.systemType)
#endif
.font(.system(size: 21))
.multilineTextAlignment(.center)
.frame(height: 30)
.focused($focus, equals: .manual)
.overlay(alignment: .trailing) {
Button(action: action) {
Image(systemName: "checkmark.circle.fill")
HStack {
TextField(title, text: $value)
#if !os(macOS)
.keyboardType(keyboardType.systemType)
#endif
.font(.system(size: 21))
.multilineTextAlignment(.center)
.frame(height: 30)
.focused($focus, equals: .manual)
.overlay(alignment: .trailing) {
Button(action: performAction) {
Image(systemName: "checkmark.circle.fill")
}
.padding(.trailing, 4)
}
.padding(.trailing, 4)
}
.background(Color.secondary.opacity(0.1))
.cornerRadius(8)
.padding([.leading, .trailing], 8)
.background(Color.secondary.opacity(0.1))
.cornerRadius(8)
.padding([.leading, .trailing], 8)
}
#elseif os(watchOS)
HStack {
TextField("", text: $value)
Expand All @@ -63,3 +64,13 @@ struct ManualInput: View {
#endif
}
}

private extension ManualInput {
func performAction() {
// This avoids crashing because the text field doesn't want to resign
// from first responder when the ComboPicker is displayed
// in a List.
focus = nil
action()
}
}
2 changes: 1 addition & 1 deletion Sources/ComboPicker/Views/SmartPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct SmartPicker<Model: ComboPickerModel, Formatter: ValueFormatterType>: View
)
.compositingGroup()
.contentShape(Rectangle())
.frame(height: 30)
.frame(height: Constants.pickerHeight)
.clipped()
.onTapGesture { action() }
.focused($focus, equals: .picker)
Expand Down
12 changes: 7 additions & 5 deletions Sources/ComboPicker/Views/iOS/NativePicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct NativePicker<Content: ComboPickerModel, Formatter: ValueFormatterType>: U
}

func makeUIView(context: UIViewRepresentableContext<Self>) -> UIPickerView {
let picker = UIPickerView()
let picker = OneLinePickerView()
picker.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
picker.dataSource = context.coordinator
picker.delegate = context.coordinator
Expand All @@ -52,10 +52,6 @@ struct NativePicker<Content: ComboPickerModel, Formatter: ValueFormatterType>: U
return 1
}

func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
return 90
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return parent.content.wrappedValue.count
}
Expand All @@ -68,5 +64,11 @@ struct NativePicker<Content: ComboPickerModel, Formatter: ValueFormatterType>: U
parent.selection.wrappedValue = parent.content.wrappedValue[row].value
}
}

class OneLinePickerView: UIPickerView {
override var intrinsicContentSize: CGSize {
.init(width: UIView.noIntrinsicMetric, height: Constants.pickerHeight + Constants.pickerPadding)
}
}
}
#endif

0 comments on commit f0bb696

Please sign in to comment.