iOS Swift SwiftUI - Use NavigationLink after clicking on subtext - ios

I got this text:
Text("Indem du fortfährst, stimmst du unseren ") +
Text("Nutzungsbedingungen")
.underline()
.foregroundColor(Color("ClickableLink")) +
Text(" und unserer ") +
Text("Datenschutzerklärung")
.underline()
.foregroundColor(Color("ClickableLink")) +
Text(" zu")
I'd like to open a new view using NavigationLink after taping on Nutzungsbedingungen or Datenschutzerklärung, both need to open different views.
I've seen those answers:
SwiftUI tappable subtext
but those are either not what I need or trying them gives me errors and I don't know how to modify them since I'm absolutely new to swift/swiftui

Here are two possible approaches, one using the new NavigationStack with NavigationDestination and the other using popOver.
Both have the downside that you can't concatenate Text views within them. But you can still work with HStack/VStack to define the layout.
enum Legals: Identifiable {
case nutzungsbedingungen
case datenschutzerklärung
var id: Legals { self }
}
struct ContentView: View {
#State private var selected: Legals?
var body: some View {
NavigationStack {
// NavigationLink version
VStack(alignment: .leading) {
Text("Indem du fortfährst, stimmst du unseren")
NavigationLink("Nutzungsbedingungen", value: Legals.nutzungsbedingungen)
Text("und unserer")
NavigationLink("Datenschutzerklärung", value: Legals.datenschutzerklärung)
Text("zu")
}
.navigationDestination(for: Legals.self) { selection in
switch selection {
case .datenschutzerklärung:
Text("Datenschutzerklärung")
case .nutzungsbedingungen:
Text("Nutzungsbedingungen")
}
}
Divider()
// popOver Version
VStack(alignment: .leading) {
Text("Indem du fortfährst, stimmst du unseren ")
Text("Nutzungsbedingungen")
.underline()
.onTapGesture {
selected = .nutzungsbedingungen
}
Text("und unserer ")
Text("Datenschutzerklärung")
.underline()
.onTapGesture {
selected = .nutzungsbedingungen
}
Text("zu")
}
.popover(item: $selected) { selected in
switch selected {
case .datenschutzerklärung:
Text("Datenschutzerklärung")
case .nutzungsbedingungen:
Text("Nutzungsbedingungen")
}
}
}
}
}

Related

Firebase Analytics - How to see specific content and not a controller?

I have an app full of stories, and I want to see which stories users are reading.
I already installed Firebase Analytics, but all I'm seeing is this kind of content:
I want to be able to see the specific title of the stories users are reading.
This is the ForEach loop I'm using:
ForEach(modelData.stories.shuffled()) { item in
if item.paid == false {
NavigationLink {
StoryDetails(story: item)
} label: {
GeneralCard(isLocked: false, story: item)
}
}
}
And on StoryDetails I have this code, I would like to see the title of the story inside Firebase Analytics.
VStack (spacing: 0) {
Text(story.title)
.font(AppFont.detailTitle())
.bold()
.multilineTextAlignment(.center)
.foregroundColor(.mainColor)
Text(story.category.rawValue)
.font(AppFont.detailDescription())
.multilineTextAlignment(.center)
.padding()
.foregroundColor(.mainColor)
VStack(alignment: .leading, spacing: 20) {
ForEach(story.text, id: \.self) { item in
VStack {
Text(item)
.font(AppFont.detailText())
}
}
}
//.padding(.horizontal, 10)
}
Is this something that can be achieved?
Thanks in advance
You could set this up by manually logging your screenviews instead. For SwiftUI, it is something like this:
struct ContentView: View {
var body: some View {
Text("Hello, world!")
// Logging screen name with class and a custom parameter.
.analyticsScreen(name: "main_content",
class: "ContentView",
extraParameters: ["my_custom_param": 5])
// OR Logging screen name only, class and extra parameters are optional.
.analyticsScreen(name: "main_content")
}
}

SwiftUI - Error with content in a view component

I'm trying to build a reusable navigation tab in SwiftUI and I'm facing some challenges.
I come from ReactJS and wanted to create a component that I can pass the tab images and the different views.
This is the code I have so far which works pretty well:
struct Navigation<Content: View>: View {
#State var selectedIndex = 0
var tabBarImageNames: [String]
let content: [Content]
init(tabBarImageNames: [String], _ content: Content...) {
self.content = content
self.tabBarImageNames = tabBarImageNames
}
var body: some View {
VStack{
ZStack {
content[selectedIndex]
}
Spacer()
HStack {
ForEach(0 ..< tabBarImageNames.count) { tabNum in
[ ... ]
}
}
}
}
}
I can call Navigation with these arguments an everything works as expected:
Navigation(
tabBarImageNames: ["house.fill", "chart.bar.xaxis", "target", "bubble.left"],
VStack {
Text("First view")
.navigationTitle("First Tab")
},
VStack {
Text("Second view")
.navigationTitle("Second Tab")
},
VStack {
Text("Third view")
.navigationTitle("Third Tab")
},
VStack {
Text("Fourth view")
.navigationTitle("Fourth Tab")
}
)
The real problem 🚨
The issue with the above code is that if the Views I'm passing as arguments are not exactly the same (when I say exactly I literally mean exactly the same type and number of components), Xcode complains with the following error:
I'm pretty sure it's something not very difficult to solve, but given my short experience with this language I'm struggling to find the right answer. I tried to change the init content protocol to AnyView instead of Content among other things, but no luck so far.
Looking for help 🗜
Anyone with SwiftUI experience that can help me out and explain me what I'm missing? Also open to feedback on improvements on the code.
Can't use any type of library or external package btw, everything has to be built manually.
Thanks Stack overflow!

SwiftUI Picker greyed out in a List

Does anyone have a fix for this? I have a Picker in my List that doesn't respond to any user input and is greyed out, but if I move it out of the List and into a VStack it functions normally.
The majority of answers I've found to this question all say that the Picker needs to be in a Form to work (which I don't understand since it works fine in a VStack), or that its a bug in which it only works on a physical device, which I've also tested on and gotten the same result.
I'll provide a screenshot as well as the code I'm using below
import SwiftUI
struct SettingsView: View {
#Binding var age : Int
var body: some View {
VStack(alignment: .leading){
List{
Picker("Your age", selection: $age) {
ForEach(1...100, id: \.self) { number in
Text("\(number)")
}
}
}
}
}
You must embed your List inside a NavigationView, so you can actually "navigate" from "Your age" to the list of Ints.
Just add one additional layer, as shown below:
var body: some View {
VStack(alignment: .leading){
NavigationView { // This is needed to navigate to the ForEach
List {
Picker("Your age", selection: $age) {
ForEach(1..<101) { number in
Text("\(number)")
}
}
}
}
}
}

SwiftUI - Add description under a toggle switch that is part of a list

I would like to add a description below a list item, similar to Apple-like lists.
I'm using Xcode 11 for iOS 13.2
NavigationView {
List {
Section(header: Text("Account information")){
Text(User.email)
VStack(alignment: .leading){
Toggle("Daily Digest", isOn: $dailyDigest)
Text("Receive a daily email with the events occurring on that day").font(.system(size: 10))
}
}
}.listStyle(GroupedListStyle()).navigationBarTitle("Settings")
}
The description under the toggle switch, I wish it look like this:
instead of
Try using footer:
NavigationView {
List {
Section(header: Text("Account information"),
footer: Text("Receive a daily email with the events occurring on that day")) { // <- add footer
Text("asd")
VStack(alignment: .leading) {
Toggle("Daily Digest", isOn: $dailyDigest)
}
}
}.listStyle(GroupedListStyle()).navigationBarTitle("Settings")
}

Why is SwiftUI picker in form repositioning after navigation?

After clicking the picker it navigates to the select view. The item list is rendered too far from the top, but snaps up after the animation is finished. Why is this happening?
Demo: https://gfycat.com/idioticdizzyazurevase
I already created a minimal example to rule out navigation bar titles and buttons, form sections and other details:
import SwiftUI
struct NewProjectView: View {
#State var name = ""
var body: some View {
NavigationView {
Form {
Picker("Client", selection: $name) {
Text("Client 1")
Text("Client 2")
}
}
}
}
}
struct NewProjectView_Previews: PreviewProvider {
static var previews: some View {
NewProjectView()
}
}
This happens in preview mode, simulator and on device (Xcode 11.2, iOS 13.2 in simulator, 13.3 beta 1 on device).
The obviously buggy behavior can be worked around when forcing the navigation view style to stacked:
NavigationView {
…
}.navigationViewStyle(StackNavigationViewStyle())
This is a solution to my problem, but I won‘t mark this as accepted answer (yet).
It seems to be a bug, even if it may be triggered by special circumstances.
My solution won‘t work if you need another navigation view style.
Additionally, it won‘t fix the horizontal repositioning mentioned by DogCoffee in the comments.
In my opinion, it has something to do with the navigation bar. In default (no mention of .navigationBarTitle extension), the navigation display mode is set to .automatic, this should be amend to .inline. I came across another post similar to this and use their solution to combine with yours, by using .navigationBarTitle("", displayMode: .inline) should help.
import SwiftUI
struct NewProjectView: View {
#State var name = ""
var body: some View {
NavigationView {
Form {
Picker("Client", selection: $name) {
Text("Client 1")
Text("Client 2")
}
}
.navigationBarTitle("", displayMode: .inline)
}
}
}
struct NewProjectView_Previews: PreviewProvider {
static var previews: some View {
NewProjectView()
}
}
Until this bug is resolved another way to work around this issue while retaining the DoubleColumnNavigationViewStyle for iPads would be to conditionally set that style:
let navView = NavigationView {
…
}
if UIDevice.current.userInterfaceIdiom == .pad {
return AnyView(navView.navigationViewStyle(DoubleColumnNavigationViewStyle()))
} else {
return AnyView(navView.navigationViewStyle(StackNavigationViewStyle()))
}
Thanks for this thread everyone! Really helped me understand things more and get a hold of one of my problems. To share with others, I was having this problem to but I was also having this problem when I set a section to appear in a if/else statement set on a section with a toggle. When the toggle was activated it would shift the section header horizontally a few pixels.
The following is how I fixed it
Section(header: Text("Subject Identified").listRowInsets(EdgeInsets()).padding(.leading)) {
Picker(selection: $subIndex, label: Text("Test")) {
ForEach(0 ..< subIdentified.count) {
Text(self.subIdentified[$0]).tag($0)
}
}
.labelsHidden()
.pickerStyle(SegmentedPickerStyle())
I'm still having horizontal shift on my picker selection view and not sure how to fix. I created another thread to received input. Thanks again! SwiftUI Shift Picker Text Horizontal

Resources