How to manually present DatePicker in SwiftUI - swiftui

I want to show a DatePicker in SwiftUI. But the SwiftUI have no interface to customization the style of DatePicker, etc, font size ,font color . So I want to use a button to show DatePicker. After click this button , the SwiftUI DatePicker will be present.
Is there any way to implement this?
struct ContentView: View {
#State private var date = Date()
var body: some View {
VStack {
ZStack() {
DatePicker(selection: $date, in: ...Date(), displayedComponents: .date) {
Text("")
}
.opacity(0.01)
HStack() {
Text("Start Time")
Spacer()
Button("2021-08-22") {
print("Button was tapped")
// present DatePicker...
}
}
}
.frame(height: 44)
.padding(.horizontal, 20)
}
}
}

I find a solution as bellow:
struct ContentView: View {
#State private var date = Date()
var body: some View {
VStack {
ZStack() {
HStack() {
Text("Start Time")
Spacer()
Text("2021-08-22")
}
DatePicker(selection: $date, in: ...Date(), displayedComponents: .date) {
Text("")
}
.opacity(0.011)
}
.frame(height: 44)
.padding(.horizontal, 20)
}
}
}

Related

how to create picker menu like drop down in SwiftUI

I am using a picker. Onclick textField, it shows the picker menu. But picker options show the top of the textField. Onclick textField toggle shows
Here is the image
Here is my code:
struct PickerView: View {
#State private var text:String = ""
#State private var options = ["Option 1", "Option 2", "Option 3"]
#State private var selectedOption = "Option 1"
#State private var showPicker: Bool = false
var body: some View {
VStack {
HStack {
TextField("", text: $selectedOption)
.disabled(true)
Image(systemName: "chevron.down")
.foregroundColor(.gray)
}
.padding()
.background(Color.gray)
.cornerRadius(5.0)
Picker("Options", selection: $selectedOption) {
ForEach(options, id: \.self) { option in
Text(option).tag(option)
}
}
.pickerStyle(.automatic)
.padding()
.background(Color.white)
.cornerRadius(5.0)
.shadow(radius: 5)
.offset(y: -100)
.opacity(showPicker ? 1 : 0)
.animation(.default)
}
.onTapGesture {
self.showPicker.toggle()
}
}
}
How to show the picker onClick textField directly like drop down?
Please help me..
This might be what you wanted
var body: some View {
VStack(alignment: .leading) {
HStack {
Picker("Options", selection: $selectedOption) {
ForEach(options, id: \.self) { option in
Text(option).tag(option)
}
}
.tint(.black)
.pickerStyle(.menu)
Spacer()
}
.background(.gray)
.cornerRadius(5.0)
}
}

Centering Item Inside Horizontal Stack with left and right views doesn't work with DatePicker

There was a similar question Center Item Inside Horizontal Stack that I followed the Asperi's basic answer that suited for me ( other answer did not worked, too).
struct HeaderTestView: View {
#State private var currentDate = Date()
var body: some View {
ZStack {
HStack {
HStack {
Button(action: {
}) {
Image(systemName: "arrowtriangle.left.fill")
}
}
Spacer()
HStack {
Button(action: {
}) {
Image(systemName: "arrowtriangle.right.fill")
}
}
}
HStack {
Text("Title")
DatePicker("Date", selection: $currentDate, displayedComponents: [.date])
}
}
}
}
My Center Item are a Text and a DatePicker, everything works as expected until the date picker is placed. The title of DatePicker is placed on the left and date is placed on the right.
Without the DatePicker
With the DatePicker
Any idea to solve this beautifully so that a Text and a DatePicker are close on the center while there are two HStacks that are adjested to on the left and right
Add .fixedSize() to the HStack containing the Text view and DatePicker:
struct ContentView: View {
#State private var currentDate = Date()
var body: some View {
ZStack {
HStack {
HStack {
Button(action: {
}) {
Image(systemName: "arrowtriangle.left.fill")
}
}
Spacer()
HStack {
Button(action: {
}) {
Image(systemName: "arrowtriangle.right.fill")
}
}
}
HStack {
Text("Title")
DatePicker("Date", selection: $currentDate, displayedComponents: [.date])
}
.fixedSize() // here
}
}
}
or add .fixedSize() to the DatePicker.

Can't select Picker

I am trying to make a stock control system in SwiftUI where users can add an ingredient and then ad an amount and then select a unit of measurement(kg, g, l ,ml).
The app allows them to click a button which allows them to add an ingredient to a text-box which is created and then their input is added to a list.
I am having trouble allowing the user to also type in a number in a text-box next to the ingredient text-box and making the picker clickable
Here is my code
import SwiftUI
struct UploadView2: View {
#State var ingredients = [String]()
#State var amount = [String]()
#State var choices = ["g", "kg", "ml", "l"]
#State var choosen: String = ""
#EnvironmentObject var viewRouter: ViewRouter
func getBinding(forIndex index: Int) -> Binding<String> {
return Binding<String>(get: { ingredients[index] },
set: { ingredients[index] = $0 })
}
var body: some View {
VStack{
HStack{
Button {
print("Going Back")
viewRouter.currentPage = .UploadView
} label: {
Image(systemName: "arrow.left")
.font(.system(size: 30))
.foregroundColor(.black)
}
.padding(.horizontal)
Spacer()
Text("Add Ingredients")
.font(.system(size: 30))
.fontWeight(.bold)
Spacer()
Button {
print("Saved")
} label: {
Image(systemName: "bookmark")
.font(.system(size: 30))
.foregroundColor(.black)
}
.padding()
}
Form {
ForEach(0..<ingredients.count, id: \.self) { index in
HStack {
Button(action: { ingredients.remove(at: index) }) {
Image(systemName: "minus.circle.fill")
.foregroundColor(.red)
.padding(.horizontal)
}
TextField("Ingredient", text: getBinding(forIndex: index))
Picker("", selection: $choosen){
ForEach(choices, id: \.self) { i in
Text("\(i)").tag(i)
}
}
}
}
Button(action: { ingredients.append("") }) {
HStack {
Image(systemName: "plus")
.foregroundColor(.black)
.padding(.horizontal)
Text("add an ingredient")
.foregroundColor(.black)
}
}
}
Button {
//change view router
//add data to data class
viewRouter.currentPage = .UploadView3
} label: {
Label("next", systemImage: "arrow.right")
}
.padding()
.frame(width: 100)
.foregroundColor(Color.white)
.background(Color.red)
.cornerRadius(8)
}
}
}
struct UploadView2_Previews: PreviewProvider {
static var previews: some View {
UploadView2()
.previewDevice(PreviewDevice(rawValue: "iPhone 13"))
.previewInterfaceOrientation(.portrait)
UploadView2()
.previewDevice(PreviewDevice(rawValue: "iPhone 8"))
}
}
When i click on my click it removes the text-box like the dismiss button
My overall goal is to have a text-box to enter an ingredient and then a text-box to enter an amount and then a picker to select a unit of measurement.
How can I achieve this using my current code as much as I can?
to be able to "select" your Picker, you could try this approach, as shown in this example code:
struct ContentView: View {
#State var ingredient = ""
#State var amount = ""
#State var choosen = ""
#State var choices = ["g", "kg", "ml", "l"]
var body: some View {
HStack {
TextField("Ingredient", text: $ingredient) // <-- or your getBinding thing
TextField("Amount", text: $amount)
Picker("", selection: $choosen){
ForEach(choices, id: \.self) { i in
Text("\(i)").tag(i)
}
}
.pickerStyle(.inline)
.frame(width: 55)
.clipped() // <-- here
}
}
}

When click the image button, open new view in Swift UI

I would like to open new View after clicking on a image button in SwiftUI, any idea?
Button(action: {}) {
Image("gift")
Text("Send")
.padding(.horizontal)
}
.padding()
.foregroundColor(.white)
.background(Color.gray)
.cornerRadius(.infinity)
If you want it in a NavigationView, you can use a NavigationLink instead of a Button:
struct ContentView : View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailView()) {
Image("gift")
Text("Send")
.padding(.horizontal)
.padding()
.foregroundColor(.white)
.background(Color.gray)
.cornerRadius(.infinity)
}
}
}
}
struct DetailView : View {
var body: some View {
Text("Detail")
}
}
If you want a sheet presented, you can use the sheet modifier and a #State variable:
struct ContentView : View {
#State private var sheetPresented = false
var body: some View {
Button(action: {
sheetPresented = true
}) {
Image("gift")
Text("Send")
.padding(.horizontal)
}
.padding()
.foregroundColor(.white)
.background(Color.gray)
.cornerRadius(.infinity)
.sheet(isPresented: $sheetPresented) {
DetailView()
}
}
}
struct DetailView : View {
var body: some View {
Text("Detail")
}
}

How do I properly use NavigationView in a ZStack?

I am trying to add some filter options to sit at the top of my view, above the NavigationView. I wrote the following code that mostly does what I want, however it disabled the ability to click on the rows to get to the detailed view. I assume this is because my filter buttons are on top of the ZStack, but I'm not sure how else to get this to work.
Here is the code I wrote:
import SwiftUI
struct BonusList: View {
var bonuses = sampleBonusData
#State var showSettings = false
#State var showBonuses = false
#State var bonusEarned = true
#State var showStatePicker = false
#State var showCategoryPicker = false
var body: some View {
ZStack {
NavigationView {
List(bonuses) { item in
NavigationLink(destination: BonusDetail(bonusName: item.bonusName, bonusCode: item.bonusCode, city: item.city, sampleImage: item.sampleImage)) {
HStack(spacing: 12.0) {
Image(item.sampleImage)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 60, height: 60)
.background(Color.white)
.cornerRadius(15)
VStack(alignment: .leading) {
HStack {
Text(item.bonusName)
.font(.headline)
Spacer()
Image(systemName: "checkmark.shield")
.opacity(self.bonusEarned ? 100 : 0)
}
Text("\(item.city), \(item.state)")
.font(.subheadline)
.frame(height: 25.0)
HStack {
Text(item.bonusCategory)
.font(.caption)
.fontWeight(.bold)
.foregroundColor(.gray)
.padding(.top, 4)
Spacer()
Text(item.bonusCode)
.font(.caption)
.fontWeight(.bold)
.foregroundColor(.gray)
.padding(.top, 4)
}
}
}
}
}
.navigationBarTitle(Text("Bonuses"))
// .navigationBarHidden(true)
}
.saturation(self.bonusEarned ? 0 : 1)
HStack {
FilterByCategory(showCategoryPicker: $showCategoryPicker)
Spacer()
FilterByState(showStatePicker: $showStatePicker)
}
StatePicker(showStatePicker: $showStatePicker)
CategoryPicker(showCategoryPicker: $showCategoryPicker)
}
}
}
This is what it looks like when I run it:
If I'm understanding correctly, you have a view or two which sit higher in the ZStack that are off canvas and come in when those buttons are tapped?
You could consider using a modal and setting the view you want to show for each button as the view for the modal. This will keep your views off screen and still allow interaction with your list. Here's what I've done...
On the main view
import SwiftUI
struct MainView: View {
#State private var isPresented = false
var body: some View {
NavigationView {
VStack {
//...
}
//Modal
.sheet(isPresented: $isPresented, content: {
AddItem(showModal: self.$isPresented)
})
}
}
}
The modal's view
import SwiftUI
struct AddItem: View {
#Binding var showModal: Bool
var body: some View {
VStack {
Button(action: {
self.showModal = false
}, label: {
Text("Cancel")
})
}
}
}