I have a list view embedded in a Navigation View, however, this Navigation View is only about the screen height. This list links to a detailed view, and when a row is tapped, the Detail View only takes up half of the screen. I would like it to open a completely new window.
Screenshots:
The code is used is the following:
import SwiftUI
import CoreData
extension UIScreen{
static let screenWidth = UIScreen.main.bounds.size.width
static let screenHeight = UIScreen.main.bounds.size.height
static let screenSize = UIScreen.main.bounds.size
}
let topCardHeight: CGFloat = 350
struct HomeView: View {
#Environment(\.managedObjectContext) var moc
#FetchRequest(entity: SavedPoem.entity(), sortDescriptors: []) var savedpoems : FetchedResults<SavedPoem>
var body: some View {
VStack {
VStack (alignment: .center){
Text("Today's Poem, November 18th...")
.font(.subheadline)
.foregroundColor(.white)
.padding(.bottom)
.padding(.top, 75)
Text("No Man Is An Island")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.white)
.padding(.bottom,1)
Text("by John Donne")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.white)
.padding(.bottom, 35)
Button(action: {}) {
Text("Read Now")
.fontWeight(/*#START_MENU_TOKEN#*/.bold/*#END_MENU_TOKEN#*/)
.font(.subheadline)
.foregroundColor(.white)
.padding(15)
.border(Color.white, width: 3)
}
}
.frame(width: UIScreen.screenWidth, height: topCardHeight, alignment: .top)
.background(Color.black)
.edgesIgnoringSafeArea(.top)
.edgesIgnoringSafeArea(.bottom)
.padding(.bottom, 0)
NavigationView{
List{
ForEach(savedpoems, id:\.title) {SavedPoem in
NavigationLink (destination: ContentView()){
ZStack {
Rectangle().fill(Color.white)
.frame(width: UIScreen.main.bounds.width - 32, height: 70)
.cornerRadius(10).shadow(color: .gray, radius: 4)
HStack {
VStack (alignment: .leading){
Text("\(SavedPoem.title ?? "")").font(.headline)
.lineLimit(1)
Text("\(SavedPoem.author ?? "")").font(.subheadline)
.foregroundColor(.secondary)
}
Spacer()
}.padding()
}
// }.onDelete(perform: remove)
}
}
}
.navigationTitle("My Saved Poems")
.navigationBarHidden(true)
.edgesIgnoringSafeArea(.top)
.padding(.top, 0)
}
}
// func remove(at offsets : IndexSet) {
// for index in offsets {
// let delete = SavedPoem[index]
// self.moc.delete(delete)
// }
// try? self.moc.save()
// }
}
Any ideas? Thanks in advance.
If you need the same UI:
(The navigation view at the bottom of your top view) , here is a solution for it .
var body: some View {
#EnvironmentObject var sharedViewModel : SharedViewModel
VStack {
VStack (alignment: .center){
if sharedViewModel.currentPageIsHome {
// your top view body here ..
}
}
NavigationView{\*....*\}
}
}.onAppear {
sharedViewModel.currentPageIsHome = true
}.onDisappear {
sharedViewModel.currentPageIsHome = false
}
And you need to create an Observable object
class SharedViewModel: ObservableObject {
#Published var currentPageIsHome = false
}
And don't forget to initialize it in your SceneDelegate
ContentView().environmentObject(SharedViewModel())
Or
Clear version :
change your view hierarchy to :
NavigationView {
List{
Section(header: YourTopView()) {
// ... your list content
}
}
}
Related
I've made a custom tab bar and I'm trying to add a search bar on one of my views. For some reason half of the tab gets pushed up when the onscreen keyboard appears. Ive tried " .ignoresSafeArea(.keyboard)" literally everywhere and the only thing that happens is my icons for the tab disappear but the top of the tab still stays there. I've been trying to fix it for the last 24 hours but I'm getting nowhere, can somebody please help me with this. Thanks!
Code for Custom Tab Bar:
import SwiftUI
enum Tabs: Int {
case home = 0
case hot = 1
case favourites = 2
case settings = 3
}
struct TabBar: View {
#Binding var selectedTab : Tabs
var body: some View {
HStack (alignment: .center){
Button {
//switch to home
selectedTab = .home
} label: {
GeometryReader { geo in
if selectedTab == .home {
Rectangle()
// .ignoresSafeArea(.keyboard)
.foregroundColor(.red)
.frame(width: geo.size.width/2, height: 5)
.padding(.leading, geo.size.width/4)
}
VStack (alignment: .center){
Image(systemName: "house")
// .ignoresSafeArea(.keyboard)
.resizable()
.scaledToFit()
.frame(width: 24, height: 24)
.padding(.top, 40.0)
}
// .ignoresSafeArea(.keyboard)
.frame(width: geo.size.width, height: geo.size.height)
}
//.ignoresSafeArea(.keyboard)
.offset(y: -35)
//.ignoresSafeArea(.keyboard)
}
// .ignoresSafeArea(.keyboard)
.tint(Color.black)
Button {
//Switch views
selectedTab = .hot
} label: {
GeometryReader { geo in
if selectedTab == .hot {
Rectangle()
//.ignoresSafeArea(.keyboard)
.foregroundColor(.red)
.frame(width: geo.size.width/2, height: 5)
.padding(.leading, geo.size.width/4)
}
VStack (alignment: .center){
Image(systemName: "flame")
//.ignoresSafeArea(.keyboard)
.resizable()
.scaledToFit()
.frame(width: 24, height: 24)
.padding(.top, 40.0)
}
//.ignoresSafeArea(.keyboard)
.frame(width: geo.size.width, height: geo.size.height)
}
//.ignoresSafeArea(.keyboard)
.offset(y: -35)
}
//.ignoresSafeArea(.keyboard)
.tint(Color.black)
Button {
//Switch views
selectedTab = .favourites
} label: {
GeometryReader { geo in
if selectedTab == .favourites {
Rectangle()
//.ignoresSafeArea(.keyboard)
.foregroundColor(.red)
.frame(width: geo.size.width/2, height: 5)
.padding(.leading, geo.size.width/4)
}
VStack (alignment: .center){
Image(systemName: "star")
//.ignoresSafeArea(.keyboard)
.resizable()
.scaledToFit()
.frame(width: 24, height: 24)
.padding(.top, 40.0)
}//.ignoresSafeArea(.keyboard)
.frame(width: geo.size.width, height: geo.size.height)
}
//.ignoresSafeArea(.keyboard)
.offset(y: -35)
}
//.ignoresSafeArea(.keyboard)
.tint(Color.black)
Button {
//Switch views
selectedTab = .settings
} label: {
GeometryReader { geo in
if selectedTab == .settings {
Rectangle()
//.ignoresSafeArea(.keyboard)
.foregroundColor(.red)
.frame(width: geo.size.width/2, height: 5)
.padding(.leading, geo.size.width/4)
}
VStack (alignment: .center){
Image(systemName: "gear")
//.ignoresSafeArea(.keyboard)
.resizable()
.scaledToFit()
.frame(width: 24, height: 24)
.padding(.top, 40.0)
}//.ignoresSafeArea(.keyboard)
.frame(width: geo.size.width, height: geo.size.height)
}
//.ignoresSafeArea(.keyboard)
.offset(y: -35)
}
//.ignoresSafeArea(.keyboard)
.tint(Color.black)
}
//.ignoresSafeArea(.keyboard, edges: .all)
.frame(height: 20)
}
}
struct TabBar_Previews: PreviewProvider {
static var previews: some View {
TabBar(selectedTab: .constant(.home))
.ignoresSafeArea(.keyboard)
}
}
ignoresSafeArea is commented in all the places I tried to put it.
Here is also the code for the search bar, maybe I need to input ignoreSafeArea somewhere here?
import SwiftUI
struct SearchBarView: View {
#StateObject var im = SearchBarContents()
//#State var selectedTabs: SearchB = .search
#State private var query = ""
var body: some View {
NavigationView {
List {
ForEach(im.filteredData) { item in
HStack{
NavigationLink(destination: ItemView(item: item))
{
SBarView(item: item)
}
}
}
}
.navigationTitle("Items")
.searchable(text: $query,
placement: .navigationBarDrawer(displayMode: .always),
prompt: "Find an Item") {
}
.onSubmit(of: .search) {
im.search(with: query)
}
.onChange(of: query) { newQuery in
im.search(with: newQuery)
}
.onAppear {
im.search()
}
}
}
}
struct SearchBarView_previews: PreviewProvider {
static var previews: some View {
SearchBarView()
}
}
If there is anything missing please let me know.
Imgur link to see exactly what I mean
https://imgur.com/fv79bKh
https://imgur.com/a/Rx9Ki6c (after I add ignoresafearea)
Depends on how you have set up your project. If you have a RootView which is controlling the View to be displayed based on the selection of your Tab Bar and is also the location in the project that you would add the Custom Tab Bar, then on that root View add the modifier .ignoresSafeArea(.keyboard)
For example:
enum Tabs: Int {
case home = 0
case hot = 1
case favourites = 2
case settings = 3
}
struct RootView: View {
#State private var selectedTab = Tabs.home
var body: some View {
VStack {
switch selectedTab {
case .home:
HomeView()
case .hot:
HotView()
case .favourites:
FavouritesView()
case .settings:
SettingsView()
}
Spacer()
CustomTabBar(selectedTab: $selectedTab)
}
.ignoresSafeArea(.keyboard)
}
}
This view hold a list of pdf names which when tapped open webviews of pdf links.
The view has a search bar above the list which when tapped causes the scrollview to disappear.
struct AllPdfListView: View {
#Environment(\.presentationMode) var mode: Binding<PresentationMode>
#ObservedObject var pdfsFetcher = PDFsFetcher()
#State var searchString = ""
#State var backButtonHidden: Bool = false
#State private var width: CGFloat?
var body: some View {
GeometryReader { geo in
VStack(alignment: .leading, spacing: 1) {
HStack(alignment: .center) {
Image(systemName: "chevron.left")
Text("All PDFs")
.font(.largeTitle)
Spacer()
}
.padding(.leading)
.frame(width: geo.size.width, height: geo.size.height / 10, alignment: .leading)
.background(Color(uiColor: UIColor.systemGray4))
.onTapGesture {
self.mode.wrappedValue.dismiss()
}
HStack(alignment: .center) {
Image(systemName: "magnifyingglass")
.padding([.leading, .top, .bottom])
TextField ("Search All Documents", text: $searchString)
.textFieldStyle(PlainTextFieldStyle())
.autocapitalization(.none)
Image(systemName: "slider.horizontal.3")
.padding(.trailing)
}
.overlay(RoundedRectangle(cornerRadius: 10).stroke(.black, lineWidth: 1))
.padding([.leading, .top, .bottom])
.frame(width: geo.size.width / 1.05 )
ScrollView {
ForEach($searchString.wrappedValue == "" ? pdfsFetcher.pdfs :
pdfsFetcher.pdfs.filter({ pdf in
pdf.internalName.contains($searchString.wrappedValue.lowercased())
})
, id: \._id) { pdf in
if let parsedString = pdf.file?.split(separator: "-") {
let request = URLRequest(url: URL(string: "https://mylink/\(parsedString[1]).pdf")!)
NavigationLink(destination: WebView(request: request)
.navigationBarBackButtonHidden(backButtonHidden)
.navigationBarHidden(backButtonHidden)
.onTapGesture(perform: {
backButtonHidden.toggle()
})) {
HStack(alignment: .center) {
Image(systemName: "doc")
.padding()
.frame(width: width, alignment: .leading)
.lineLimit(1)
.alignmentGuide(.leading, computeValue: { dimension in
self.width = max(self.width ?? 0, dimension.width)
return dimension[.leading]
})
Text(pdf.internalName)
.padding()
.multilineTextAlignment(.leading)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
}
.padding(.leading)
}
}
}
.navigationBarHidden(true)
}
.accentColor(Color.black)
.onAppear{
pdfsFetcher.pdfs == [] ? pdfsFetcher.fetchPDFs() : nil
}
}
}
}
}
Pdf list and Searchbar.
The same view on Searchbar focus.
I would like the search string to filter the list of pdfs while maintaining the visibility of the list.
I was able to fix this by making my #ObservableObject an #EnvironmentObject in my App :
#main
struct MyApp: App {
#ObservedObject var pdfsFetcher = PDFsFetcher()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(pdfsFetcher)
}
}
}
struct AllPdfListView: View {
#EnvironmentObject var pdfsFetcher: PDFsFetcher
}
This question already has an answer here:
SwiftUI disable list border iOS 14 [duplicate]
(1 answer)
Closed 2 years ago.
I'm currently building out the home page for a project, and am running into some styling issues. I have a header card followed by a list of items.
The styling for this list is off and I'm not sure why:
I would like to remove the white spacing between the header "Your saved poems" and the black frame above.
I would like the list to be centred, without a divider, and with a white background (instead of grey).
I've attempted to make some changes but nothing works...
Screenshot here:
Code for the list view here:
import SwiftUI
struct SavedPoemList: View {
#Environment(\.managedObjectContext) var moc
#FetchRequest(entity: SavedPoem.entity(), sortDescriptors: []) var savedpoems : FetchedResults<SavedPoem>
var body: some View {
VStack (alignment: .leading) {
HStack{
Text("Your Saved Poems")
.font(.title)
.fontWeight(.black)
.foregroundColor(.black)
Spacer()
Button(action: {}) {
Text("Edit")
.font(.headline)
.foregroundColor(.secondary)
}
}.padding(.bottom)
List {
ForEach(savedpoems, id:\.title) {SavedPoem in
NavigationLink (destination: DetailViewSaved()){
ZStack {
Rectangle().fill(Color.white)
.frame(width: UIScreen.main.bounds.width - 32, height: 70)
.cornerRadius(10).shadow(color: .gray, radius: 5)
HStack {
VStack (alignment: .leading){
Text("\(SavedPoem.title ?? "")").font(.headline)
.lineLimit(1)
Text("\(SavedPoem.author ?? "")").font(.subheadline)
.foregroundColor(.secondary)
}
Spacer()
}.padding()
}
// }.onDelete(perform: remove)
}
}
}
.navigationTitle("My Saved Poems")
.navigationBarHidden(true)
.edgesIgnoringSafeArea(.top)
.padding(.top, 0)
.background(Color.white)
}
.padding()
.edgesIgnoringSafeArea(.bottom)
}
}
Code for the header card here:
import SwiftUI
struct HeaderView: View {
var body: some View {
NavigationView {
VStack (alignment: .center){
Text("Today's Poem, November 18th...")
.font(.subheadline)
.foregroundColor(.white)
.padding(.bottom)
.padding(.top, 75)
Text("No Man Is An Island")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.white)
.padding(.bottom,1)
Text("by John Donne")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.white)
.padding(.bottom, 35)
NavigationLink (destination: DetailViewNew()) {
Text("Read Now")
.fontWeight(/*#START_MENU_TOKEN#*/.bold/*#END_MENU_TOKEN#*/)
.font(.subheadline)
.foregroundColor(.white)
.padding(15)
.border(Color.white, width: 3)
}
}
.frame(width: UIScreen.screenWidth, height: topCardHeight, alignment: .top)
.background(Color.black)
.edgesIgnoringSafeArea(.top)
.padding(.bottom, 0)
}
}
}
Code for the Home Screen here:
import SwiftUI
import CoreData
extension UIScreen{
static let screenWidth = UIScreen.main.bounds.size.width
static let screenHeight = UIScreen.main.bounds.size.height
static let screenSize = UIScreen.main.bounds.size
}
let topCardHeight: CGFloat = 350
struct HomeView: View {
#Environment(\.managedObjectContext) var moc
#FetchRequest(entity: SavedPoem.entity(), sortDescriptors: []) var savedpoems : FetchedResults<SavedPoem>
var body: some View {
NavigationView{
VStack {
HeaderView()
SavedPoemList()
}
}
// func remove(at offsets : IndexSet) {
// for index in offsets {
// let delete = SavedPoem[index]
// self.moc.delete(delete)
// }
// try? self.moc.save()
// }
}
Any ideas? Thanks a lot in advance.
You have a NavigationView in HomeView and then another one in HeaderView. I suggest you change the NavigationView in HeaderView to a VStack.
List has limited customization options. You should probably use LazyVStack.
I'm trying to pass FetchResult Data from one screen to another, through a Navigation Link in a ScrollView.
When I try to call the passed data in the DetailView screen, I get the following error:
Instance member "" cannoth be used on type "SavedPoem"
Code below - Saved Poem List
import SwiftUI
struct SavedPoemList: View {
#Environment(\.managedObjectContext) var moc
#FetchRequest(entity: SavedPoem.entity(), sortDescriptors: []) var savedpoems : FetchedResults<SavedPoem>
var body: some View {
VStack (alignment: .leading, spacing: 0) {
HStack{
Text("Your Saved Poems")
.font(.title)
.fontWeight(.black)
.foregroundColor(.black)
Spacer()
}.padding(.bottom)
.padding(.trailing)
.padding(.leading)
ScrollView {
ForEach(savedpoems, id:\.title) {SavedPoem in
NavigationLink (destination: DetailViewSaved()){
ZStack {
Rectangle()
.fill(Color.white)
.frame(width: UIScreen.screenWidth - 40, height: 70)
.cornerRadius(5)
.padding([.horizontal], 20)
// .shadow(color: .gray, radius: 10)
HStack {
VStack (alignment: .leading){
Text("\(SavedPoem.title ?? "")")
.font(.headline)
.foregroundColor(.black)
.lineLimit(1)
.padding(.bottom, 3)
Text("\(SavedPoem.author ?? "")")
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding(.trailing)
Spacer()
}
.padding()
}.padding(.bottom,10)
}
}.onDelete(perform: self.remove)
}
.navigationTitle("My Saved Poems")
.navigationBarHidden(true)
.edgesIgnoringSafeArea(.top)
.padding(.bottom, 30)
}
.padding(.horizontal, 30)
.edgesIgnoringSafeArea(.bottom)
}
func remove(at offsets : IndexSet) {
for index in offsets {
let delete = savedpoems[index]
self.moc.delete(delete)
}
try? self.moc.save()
}
}
and Code for the Detail View
import SwiftUI
struct DetailViewSaved: View {
#ObservedObject var fetch = FetchPoem()
#Environment(\.managedObjectContext) var moc
#FetchRequest(entity: SavedPoem.entity(), sortDescriptors: []) var savedpoems : FetchedResults<SavedPoem>
#State private var saved : Bool = false
var currentDate = Text(Date().addingTimeInterval(600), style: .date)
var body: some View {
VStack {
HStack{
// NavigationLink( destination: HomeView())
// {
//
// Image(systemName: "arrow.backward")
// .font(.system(size: 25, weight: .heavy))
// .foregroundColor(.black)
// }
Spacer(minLength: 0)
Button(action:
{
// self.moc.delete(delete)
try? self.moc.save()
}) {
Image(systemName: saved ? "bookmark.fill": "bookmark")
.font(.system(size: 25, weight: .heavy))
.foregroundColor(.black)
}
}
ScrollView {
VStack {
HStack{
VStack (alignment: .leading) {
Text("Today's Poem, \(currentDate)")
.font(.subheadline)
.foregroundColor(Color.gray)
.padding(.bottom, 20)
.padding(.top, 10)
Text("\(SavedPoem.title ?? "")")
// .font(.largeTitle)
// .fontWeight(.heavy)
// .foregroundColor(.black)
// .padding(.bottom, 20)
// .lineSpacing(0)
// Text("BY "+poem.author.uppercased())
Text("BY \(SavedPoem.author ?? "")")
// .font(.subheadline)
// .foregroundColor(Color.gray)
// .padding(.bottom, 20)
HStack {
Text("\(SavedPoem.lines ?? "")")
// .font(.body)
// .foregroundColor(.black)
// .padding(.bottom)
// .lineSpacing(5)
//
Spacer()
}
Spacer()
}
.padding()
}
}
}
}
}
}
Am I missing anything? How can I resolve this issue, and pass the data from the Fetchedresults in the list view to the detailed screen?
Thanks in advance.
EDITED CODE FOR REPLY
SavedPoemList:
import SwiftUI
struct SavedPoemList: View {
#Environment(\.managedObjectContext) var moc
#FetchRequest(entity: SavedPoem.entity(), sortDescriptors: []) var savedpoems : FetchedResults<SavedPoem>
var body: some View {
VStack (alignment: .leading, spacing: 0) {
HStack{
Text("Your Saved Poems")
.font(.title)
.fontWeight(.black)
.foregroundColor(.black)
Spacer()
Text("Edit")
.font(.subheadline)
.fontWeight(.black)
.foregroundColor(.gray)
}.padding(.bottom)
.padding(.trailing)
.padding(.leading)
ScrollView {
ForEach(savedpoems, id:\.title) {SavedPoem in
NavigationLink (destination: DetailViewSaved(savedPoem: SavedPoem)){
ZStack {
Rectangle()
.fill(Color.white)
.frame(width: UIScreen.screenWidth - 40, height: 70)
.cornerRadius(5)
.padding([.horizontal], 20)
// .shadow(color: .gray, radius: 10)
HStack {
VStack (alignment: .leading){
Text("\(SavedPoem.title ?? "")")
.font(.headline)
.foregroundColor(.black)
.lineLimit(1)
.padding(.bottom, 3)
Text("\(SavedPoem.author ?? "")")
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding(.trailing)
Spacer()
}
.padding()
}.padding(.bottom,10)
}
}.onDelete(perform: self.remove)
}
.navigationTitle("My Saved Poems")
.navigationBarHidden(true)
.edgesIgnoringSafeArea(.top)
.padding(.bottom, 30)
}
.padding(.horizontal, 30)
.edgesIgnoringSafeArea(.bottom)
}
func remove(at offsets : IndexSet) {
for index in offsets {
let delete = savedpoems[index]
self.moc.delete(delete)
}
try? self.moc.save()
}
}
DetailView
import SwiftUI
struct DetailViewSaved: View {
#ObservedObject var fetch = FetchPoem()
#Environment(\.managedObjectContext) var moc
#FetchRequest(entity: SavedPoem.entity(), sortDescriptors: []) var savedpoems : FetchedResults<SavedPoem>
#State private var saved : Bool = false
var savedPoem : SavedPoem
var currentDate = Text(Date().addingTimeInterval(600), style: .date)
var body: some View {
VStack {
HStack{
// NavigationLink( destination: HomeView())
// {
//
// Image(systemName: "arrow.backward")
// .font(.system(size: 25, weight: .heavy))
// .foregroundColor(.black)
// }
Spacer(minLength: 0)
Button(action:
{
// self.moc.delete(delete)
try? self.moc.save()
}) {
Image(systemName: saved ? "bookmark.fill": "bookmark")
.font(.system(size: 25, weight: .heavy))
.foregroundColor(.black)
}
}
ScrollView {
VStack {
HStack{
VStack (alignment: .leading) {
// Text("Today's Poem, \(currentDate)")
// .font(.subheadline)
// .foregroundColor(Color.gray)
// .padding(.bottom, 20)
// .padding(.top, 10)
Text("\(savedPoem.title ?? "")")
// .font(.largeTitle)
// .fontWeight(.heavy)
// .foregroundColor(.black)
// .padding(.bottom, 20)
// .lineSpacing(0)
// Text("BY "+poem.author.uppercased())
// Text("BY \(SavedPoem.author ?? "")")
// .font(.subheadline)
// .foregroundColor(Color.gray)
// .padding(.bottom, 20)
// HStack {
// Text("\(SavedPoem.lines ?? "")")
// .font(.body)
// .foregroundColor(.black)
// .padding(.bottom)
// .lineSpacing(5)
//
Spacer()
}
Spacer()
}
.padding()
}
}
}
}
}
}
struct DetailViewSaved_Previews: PreviewProvider {
static var previews: some View {
DetailViewSaved(savedPoem: SavedPoem)
}
}
I made an example with your case :
SavedPoemList : Pass an item from your array to your Detail View like that :
NavigationLink (destination: DetailViewSaved(savedPoem: SavedPoem)){
VStack{
Text("Your row view")
}
}
and to receive it in your Detail View :
struct DetailViewSaved: View {
var savedPoem : SavedPoem
var body: some View {
Text("Your view")
}
}
In my code I get this error and I cannot figure out how to resolve it. The error is in the Trailing block of code
struct Map: View {
#ObservedObject public var dataManager = DataManager.shared
#Binding public var seqId: String
// rz- to pass seqId to second view
// #State public var seqId2: String = ""
var body: some View {
ZStack {
VStack {
Text("Results").foregroundColor(Color.white).onAppear{self.dataManager.downloadSeqData(seqId: self.seqId)} .onAppear(perform: playSound)/*rz want to add this sound func to contentview somehow, otherwise it will constantly play sound when page loads */ .edgesIgnoringSafeArea(.all)
//rz- if strand is linear draw line
if dataManager.dataSet?.INSDSeq.topology == "linear" {
Rectangle()
.fill(Color.black)
.frame(width: 500, height: 20)
}
//rz- if strand is circular draw o
if dataManager.dataSet?.INSDSeq.topology == "circular" {
Circle()
.stroke(Color.black, style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))
.frame(width: 500, height: 500)
}
if dataManager.dataSet?.INSDSeq.topology != "circular" && dataManager.dataSet?.INSDSeq.topology != "linear"{
Text("Data Unavailable, try a new accession number.")
}
}
.navigationBarItems(
//rz - added home and genbank view to navigation bars
leading:
NavigationLink(destination: ContentView()) {
Text("New Query")
.font(.title)
.foregroundColor(Color.black)
},
trailing:
NavigationLink(destination: Screen(seqId: self.$seqId)) {
Text("GenBank View")
.font(.title)
.foregroundColor(Color.black)
Error is in $seqId
NavigationLink(destination: Screen(seqId: self.$seqId)) {
Here is the Screen view
import SwiftUI
struct Screen: View {
#ObservedObject public var dataManager = DataManager.shared
#State private var seqId: String = ""
var body: some View {
VStack {
TextField("Enter Accession Number", text: $seqId)
.padding()
Button("Search")
{
dataManager.downloadSeqData(seqId: seqId)
}
ScrollView {
VStack(alignment: .leading) {
Text(dataManager.dataSet?.INSDSeq.locus ?? "")
.padding()
Text(dataManager.dataSet?.INSDSeq.organism ?? "").padding()
Text(dataManager.dataSet?.INSDSeq.source ?? "").padding()
Text(dataManager.dataSet?.INSDSeq.taxonomy ?? "").padding()
Text(dataManager.dataSet?.INSDSeq.topology ?? "").padding()
Text(dataManager.dataSet?.INSDSeq.length == nil ? "" : "\(dataManager.dataSet!.INSDSeq.length)") .padding()
Text(dataManager.dataSet?.INSDSeq.strandedness ?? "").padding()
Text(dataManager.dataSet?.INSDSeq.moltype ?? "").padding()
Text(dataManager.dataSet?.INSDSeq.sequence ?? "").padding()
}
.cornerRadius(10)
VStack(alignment: .leading, spacing: 10) {
ForEach(dataManager.featureList, id:\.self) { feature in
VStack (alignment: .leading){
VStack (alignment: .leading) {
Text(feature.INSDFeature_key).bold()
Text(feature.INSDFeature_location)
}.padding()
IntervalSection(feature: feature)
QualsSection(feature: feature)
}
.cornerRadius(10)
}
}
.cornerRadius(20)
}
.padding(.horizontal)
}
}
}
struct IntervalSection: View {
var feature: INSDFeature
var body: some View {
VStack (alignment: .leading){
ForEach(0..<feature.INSDFeature_intervals.count, id: \.self) { i in
ForEach(0..<feature.INSDFeature_intervals[i].INSDInterval.count, id: \.self) { j in
if let from = feature.INSDFeature_intervals[i].INSDInterval[j].INSDInterval_from {
VStack (alignment: .leading){
Text("\(from)").bold()
Text("\(feature.INSDFeature_intervals[i].INSDInterval[j].INSDInterval_to ?? -1)")
}
.padding()
.cornerRadius(10)
}
}
}
}
}
}
struct QualsSection: View{
var feature: INSDFeature
var body: some View {
VStack (alignment: .leading){
ForEach(0..<feature.INSDFeature_quals.count , id: \.self) { i in
ForEach(0..<feature.INSDFeature_quals[i].INSDQualifier.count , id: \.self) { j in
VStack (alignment: .leading){
Text(feature.INSDFeature_quals[i].INSDQualifier[j].INSDQualifier_name).bold()
Text(feature.INSDFeature_quals[i].INSDQualifier[j].INSDQualifier_value)
}
.padding()
.cornerRadius(10)
}
}
}
}
}
In SwiftUI you should use Binding instead of State in cases, where the data is coming from another view. Furthermore both attributes of Screen are private, therefore they can't be accessed in this case set from outside of the struct itself.
I would suggest to make seqID in Screen public like you did it with dataManager and change it to State