SwiftUI: Create a custom view that behaves like a SwiftUI List, taking multiple views in a closure and arranging them [closed] - swiftui

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 months ago.
Improve this question
I am currently trying to create a custom view in SwiftUI that basically behaves like a SwiftUI List or Form. What I want is to achieve is something like the following:
CustomView {
Text("TBD")
Text("TBD")
Image(systemName: "heart")
}
The output of this custom view should then be a vertical list of the views that were passed in, plus some additional elements, like dividers. Something like what you would get from the following code:
VStack(alignment: .leading) {
Text("TBD")
Divider()
Text("TBD")
Divider()
Image(systemName: "heart")
}
The problem is that I have no idea how to create a generic view that would take any number of other views and then arrange them in such a way - Im not even sure if it is possible.
If there is anyone around that has experience with creating something like this, I would appreciate any hints or explanations.
Thanks!

Here is an example that works for 3 views:
struct CustomView: View {
let children: [AnyView]
init<C1: View, C2: View, C3: View>(#ViewBuilder content: () -> TupleView<(C1, C2, C3)>) {
self.children = [AnyView(content().value.0),
AnyView(content().value.1),
AnyView(content().value.2)]
}
var body: some View {
VStack(alignment: .leading) {
children[0]
Divider()
children[1]
Divider()
children[2]
}
}
}
I believe you need an init for each number of Views you want to support. Read more about this here:
https://forums.swift.org/t/swiftui-viewbuilder-result-is-a-tupleview-how-is-apple-using-it-and-able-to-avoid-turning-things-into-anyview/28181/14

Related

How do I send user inputs to a database using the forms feature in swift UI? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I’m new to swift UI and programming in general. I’ve learnt the basics so far and now I want to be able to setup a simple form in my app. I can design the form no problem. But I’m not sure what function to call CIA the button action or the code to get that information from the user to a database. Can someone help to explain how to set that up and which database to use to collect the user information?
I can't set the database up for you, as each database has its unique ways of doing so. However, I am giving you a basic structure that would help you link your SwiftUI view to the back-end(your database).
Setting up your form
import SwiftUI
struct ContentView: View {
#State var firstName = ""
#State var lastName = ""
#State var age = ""
var body: some View {
TextField("Enter First Name", text: $firstName)
TextField("Enter Last Name", text: $lastName)
TextField("Age", text: $age)
Button(action: {
addUser(firstName: firstName, lastName: lastName, age: Int(age) ?? 0)
}) {
Text("Save to database")
}
}
}
Saving result to back-end:
import CoreData
func addUser(firstName: String, lastName: String, age: Int) {
/*
code here would be using Core Data structure
do not copy paste, only used as reference
*/
let newUser = User(context: context)
newUser.firstName = firstName
newUser.lastName = lastName
newUser.age = age
do {
try context.save()
print("Successfully saved to Core Data.")
} catch {
print(error.localizedDescription)
}
}
Keep in mind that you would have to do your own research on how to save results using your own database. The code in addUser() would not work if you are using something other than Core Data. In your case, I would suggest you to try Firebase and perhaps, you could use Firebase Firestore as it seems like it suits your needs.

How do you prevent SwiftUI from autoresizing view when keyboard appears [duplicate]

This question already has answers here:
iOS 14 SwiftUI Keyboard lifts view automatically
(4 answers)
Closed 2 years ago.
I have a TextField in my iOS app, and it is positioned such that I don't want it to move when the keyboard appears. However, the view is autoresizing when the keyboard appears. Is there a way to prevent this?
import SwiftUI
struct test: View {
#State var text: String = ""
var body: some View {
TextField("Type", text: self.$text)
}
}
You can use a modifier to tell a certain view to ignore specific or all iOS safe areas. Apply the following .ignoresSafeArea(.keyboard) to the parent view, and it will not resize when the keyboard is open.

How can I delay the obscuring/masking of characters in SwiftUI's SecureField so that each typed character shows for ~1sec before it's hidden? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
When using SwiftUI's SecureField the user's input it obscured / masked / turned into • immediately, which makes it difficult to confirm that one has actually typed the password correctly. Several of our users have complained about this, and it seems that most people expect to see the character they typed for about a second or so before it disappears, which gives them visual confirmation that they tapped the correct letter and can now move on w/o worrying.
Is it possible to add a delay in there and show the last typed character for a moment?
I don't think this is possible in SwiftUI at the moment, but here's the hack we've been using in the meantime. It stacks a SecureField on top of a TextField and toggles their opacities when the user clicks on the eye (to show the text). Granted, it shows the entire String and not the last letter, but it works.
I'm sure there are open source libraries of ways to do this in UIKit that you could convert, but I'll let someone else answer that.
struct SecureTextFieldView: View {
#State var text: String = ""
#State var showText: Bool = false
var body: some View {
ZStack {
TextField("Password", text: $text)
.opacity(showText ? 1.0 : 0.0)
SecureField("Password", text: $text)
.opacity(showText ? 0.0 : 1.0)
}
.padding()
.background(
Color(UIColor.secondarySystemBackground).cornerRadius(10)
)
.overlay(
Image(systemName: "eye.fill")
.foregroundColor(showText ? .black : .gray)
.padding(.trailing)
.onLongPressGesture(minimumDuration: 20, maximumDistance: 30, pressing: { (_) in
showText.toggle()
}, perform: {})
, alignment: .trailing
)
.padding()
}
}
struct SecureTextFieldView_Previews: PreviewProvider {
static var previews: some View {
SecureTextFieldView()
}
}

Use LazyVStack in SwiftUI 1

One of the new features of SwiftUI 2 are LazyVStacks. Is it possible to implement its functionality in the current SwiftUI framework? I have the following code sample where I want to use it:
var body : some View {
VStack(alignment: .leading){
ScrollView {
Text("sample")
VStack{ // I want to have a LazyVStack here
ForEach(1..<10000, id: \.self) {_ in
Text("test")
}
}
}
}
}
Normally i would use a List which is by default lazy. But due to other constraints it's not possible.
Thanks in advance.
You have to install Xcode 12 beta in order to use LazyStacks. If you are coding for an iOS app, the simulator will run correctly, but if you are coding for a macOS app you will have to update to Big Sur also in order to run the SwiftUI 2 code.

How to do Apple Music-like navigation in SwiftUI? Custom List and NavigationView has highlight not going away

This is my example that I am trying to get to work:
struct ContentView: View {
let links = ["Item 1", "Item 2", "Item 3", "Item 4"]
var body: some View {
NavigationView {
ScrollView {
Text("My Title")
List(links, id: \.self) {
link in
NavigationLink(destination: TestView()) {
Text(link)
.padding(.vertical, 4)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
.frame(height: 178)
Text("Some more content here")
}
}
}
}
Note: TestView is just some view with the text hello world on it.
I am trying to copy Apple Music's style of navigation. I tried putting a Button in the NavigationLink but tapping it on the text wouldn't change views, and I couldn't find a way to reliably change the color of the row when tapped, at the same time. Also in some approach, I managed to make it work, but the way the colors animate is different, i.e. it fades from A to B, over ~100ms whereas what I'm trying to achieve is to animate between the states instantly (like in Apple Music).
My current approach is using a List, putting NavigationLinks inside it and then cutting off the whole view by giving it a height. This way I can put it alongside other content.
It's working fine for now, but whenever I click on an row and go back, the row is still highlighted, when it shouldn't. Is there a way to make it so that it deselects when going back to the screen somehow?
I think this bug is being caused by the List being inside a ScrollView, since when I removed ScrollView, the list worked properly, and there wasn't this highlight bug. But I need to be able to put my content with the list, and I don't intend to have a list take up the whole screen.
Is there any way to fix this bug with this approach? I'm also willing for other ways to achieve the same result without using List.
Trying to use ForEach instead ofList?
With a view for row (CustomRow) where you can pass link item and set custom dividing line, background etc ...
ForEach(links, id: \.self) { link in
NavigationLink(destination: TestView()) {
CustomRow(item: link)
}
}
.frame(height: 178)