How can I navigate to different views? - swiftui

I am learning to use Swiftui and I need your help. The following pickers are present in my project:
Picker(selection: $selectedChoose, label: Text("Cosa ti serve?")) {
ForEach(0 ..< choose.count) {
Text(self.choose[$0]).tag($0)
}
}.pickerStyle(SegmentedPickerStyle())
//WheelPickerStyle
Picker(selection: $selectedCountry, label: Text("Città")) {
ForEach(0 ..< country.count) {
Text(self.country[$0]).tag($0)
}
}
Picker(selection: $selectedAppartamento, label: Text("Tipo appartamento")) {
ForEach(0 ..< appartamento.count) {
Text(self.appartamento[$0]).tag($0)
}
}
Picker(selection: $selectedCamera, label: Text("Tipo camera")) {
ForEach(0 ..< camera.count) {
Text(self.camera[$0]).tag($0)
}
}
At the end of the View, I have the following Text to which I will add the NavigationLink:
Text("Mostra annunci")
.font(Font.custom("Helvetica Neue", size: 15))
.foregroundColor(.white)
.frame(width: 150, height: 30).foregroundColor(Color.white)
.background(Color(red: 0.649, green: 0.18, blue: 0.117)).cornerRadius(10).padding(15)
Is it possible to link user choices with different views? I mean, if a user selects a different city, room type and type of apartments, how can I link these choices to different views? Each view should show results based on the different choices made by the user in the pickers above. How can I do that?
Thank you in advance :)

you can popup new views using the .sheet(...). The restriction is that you can only have one of those. So you would have to do something like this:
.sheet(isPresented: $showSheet) {
if self.selectedCountry == "myCountry" {
Text("myCountry")
}
else if self.selectedCountry == "yourCountry" {
Text("yourCountry")
}
... lots of other if else
In your case I would reconsider the whole structure. Use just one sheet option and
pass in the choices the user made. And inside the new view present the data as chosen.

Related

Trouble With Constraints for a Navigation Link

Here is my code:
import SwiftUI
struct ContentView: View {
var link: some View {
NavigationLink(destination: OtherView()) {
Text("NLTitle")
}
.foregroundColor(.blue)
}
var body: some View {
NavigationView {
List {
ZStack {
HStack {
Text("1")
Spacer()
}.padding([.leading, .trailing], 20)
HStack {
Spacer()
Text("2")
.multilineTextAlignment(.center)
.frame(
alignment: .center
)
Spacer()
}
.padding([.leading, .trailing], 20)
HStack {
Spacer()
link
}.padding([.leading, .trailing], 20)
}
}
}
}
}
I have a NavigationLink (named 'link') in a list cell. I would like for the Text within 'link' to be to the rightmost side of the view. To try to accomplish this, I inserted 'link' in an HStack and put a Spacer() before it to try and push it to the rightmost part of the view. When I run the app though, the Text ends up in between Text("1") and Text("2") and I can't figure out why. I want Text("1") to be in the leftmost part of the view, Text("2") to be in the center of the view, and 'link' to be in the rightmost part of the view. I have provided visuals (the colors aren't important, I just wanted to make the different Texts clear):
Desired layout:
What I get instead:
I found that if I take everything out of the List view I get my desired layout. Also, if I keep everything in the List view and replace the NavigationLink with a Button I get my desired layout. The goal is to get the desired layout without having to change either of these aspects.
For the sake of clarity, I didn't include the code for OtherView() as I don't think it's necessary for this question.
The "quick" fix is to add fixedSize() to the NavigationLink
var link: some View {
NavigationLink(destination: Text("OtherView()")) {
Text("NLTitle")
}
.foregroundColor(.blue)
.fixedSize()
}
That will allow the link to shrink.

Rounded corners and border for a SwiftUI List Section

I want to create the following design in SwiftUI. I am currently using a list and creating a section that contains cells like so.
List {
Section {
ForEach(titles) { title in
Cell(title: title)
}
}
}
When I apply a modifier like a border to the section it applies it to all the views contained in the Section. I want to have that border around the entire Section with a corner radius of 10. The closest I have got to creating the desired design is by not using a List but instead using a VStack and applying the following modifiers
VStack {
ForEach(titles) { title in
Cell(title: title)
}
}
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(.gray, lineWidth: 2))
I discovered however that this is not a smart approach as the List uses reusable cells and in the case of VStack they do not. Is it possible to create the wanted design with a List in SwiftUI? I do not want to opt for the default list style provided by Apple
Just Copy paste this code and customise it as per your needs, enjoy
import SwiftUI
struct CustomizeListView: View {
var titles = ["First Section" : ["Manage your workout", "View recorded workouts", "Weight tracker", "Mediation"], "Second Section" : ["Your workout", "Recorded workouts", "Tracker", "Mediations"]]
var body: some View {
List {
ForEach(titles.keys.sorted(by: <), id: \.self){ key in
Section(key) {
VStack(alignment: .leading, spacing: 0){
ForEach(titles[key]!, id: \.self) { title in
HStack{
Text(title)
Spacer()
Image(systemName: "arrow.right")
}//: HSTACK
.padding(20)
Divider()
}//: LOOP
}//: VSTACK
.overlay(
RoundedRectangle(cornerRadius: 10, style: .circular).stroke(Color(uiColor: .tertiaryLabel), lineWidth: 1)
)
.foregroundColor(Color(uiColor: .tertiaryLabel))
}//: SECTION
}//: LOOP
}//: LIST
.listStyle(InsetListStyle())
}
}
struct CustomizeListView_Previews: PreviewProvider {
static var previews: some View {
CustomizeListView()
}
}
I assume you just need to change list style, like
List {
Section {
ForEach(titles) { title in
Cell(title: title)
}
}
}
.listStyle(.insetGrouped) // << here !!

Multiple Picker views: Inconsistent, cycle drop down lists

I have a form with three different picker views. When I run the app and click on one of the pickers, the drop-down content is populated from another picker and it spontaneously cycles through the other two picker contents before returning to the main view. I am gogin to kick myself when someone points to something very fundamental and basic.... but here is the code . And thanks in advance!
var body: some View {
Form{
VStack {
HStack {
Text("PaO2")
TextField("mmHg", text: $PaO2)
.keyboardType(.numberPad)
Spacer()
Text("O2(%)")
TextField("%", text: $FiO2)
.keyboardType(.numberPad)
}
Toggle("Mechnical Ventilation", isOn: $MV)
HStack {
Text("Platelets")
TextField("(x1000)", text: $Platelets)
.keyboardType(.numberPad)
}
Picker(selection: $GCSSelected, label: Text("Glasgow Coma Scale")) {
ForEach(0..<GCS.count){ index1 in
Text(self.GCS[index1]).tag(index1)
}
}
Spacer()
Picker(selection: $HDSelected, label: Text("MAP/use of vasoactive Rx")){
ForEach(0..<HD.count){ index2 in
Text(self.HD[index2]).tag(index2)
}
}
HStack{
Text("Bilirubin")
TextField("mg/dL", text: $Bili)
.keyboardType(.numbersAndPunctuation)
}
Picker(selection: $RenalSelected, label: Text("Creatinine or Urine output")){
ForEach(0..<Renal.count){ index3 in
Text(self.Renal[index3]).tag(index3)
}
}
}
}
}
}
The issue is due to used single view for entire Form content, but you should not, so
var body: some View {
Form{
VStack { // << remove this container and let every picker be in own row

Show back button in Picker content

I have a view with hidden navigation bar, but I need to show the navigation bar with back button when user select a value from picker.
When I add a leading button, my code shows all country texts as one item instead of making each Text in separate selectable row.
Any idea how to fix this issue?
VStack{
Form {
Picker(selection: $selectedCountry, label: HStack {
Text("Country")
}) {
ForEach(0 ..< countries.count) {
Text(self.countries[$0])
}
.navigationBarItems(leading: BackButton())
.navigationBarBackButtonHidden(true)
.navigationBarHidden(false)
}
.navigationBarHidden(true)
.navigationBarBackButtonHidden(false)
}
}.navigationBarTitle("")
.navigationBarHidden(true)
Applying modifiers to dynamic container, ie. ForEach, you convert it into one view, so picker shows only one combined view.
Here is possible solution - attach needed modifiers only to first item of picker (tested with Xcode 12 / iOS 14)
Form {
Picker(selection: $selectedCountry, label: HStack {
Text("Country")
}) {
ForEach(0 ..< countries.count) {
if 0 == $0 {
Text(self.countries[$0])
.navigationBarItems(leading: BackButton())
.navigationBarBackButtonHidden(true)
.navigationBarHidden(false)
} else {
Text(self.countries[$0])
}
}
}
.navigationBarHidden(true)
.navigationBarBackButtonHidden(false)
}

How to select single elements in swiftui's Canvas preview?

I know that cmnd-click can select elements in the Canvas preview window. But often, when there are many elements inside NavigationView, cmnd-click will select all of this.
NavigationView {
List {
DateView()
Picker(selection: $transactionType, label: Text("Picker")) {
Text("All").tag(0)
Text("Income").tag(1)
Text("Expenses").tag(2)
}.pickerStyle(SegmentedPickerStyle())
.padding()
ForEach(0 ..< 12) {item in
NavigationLink(destination: TransactionsDetailsView()) {
HStack(alignment: .top) {
Text("29/08/2019")
Spacer()
VStack(alignment: .trailing) {
Text("+ 1 500 THB")
.fontWeight(.heavy)
Text("morning")
}
}
}
}
.navigationBarTitle("Transactions")
}
}
I come from web dev background, so I assumed that I could select each of the elements in Canvas. The same in web inspetor in Safari. Am I wrong? Or is there a way of selecting more details on Canvas?