How to select text in several Text views at once? - swiftui

Here is a part of my view:
struct ContentView: View {
var body: some View {
VStack {
Text("test1")
Text("test2")
Text("test3")
Text("test4")
Text("test5")
}
.textSelection(.enabled)
}
}
I can select text in one view but not all the text at once. The views are more complex than this but this is the gist of it.
How can I make it so that I can select all the lines at once?
Thanks

Related

SwiftUI animating part of a view without affecting specific other part

Sorry for the cryptic title.
I would like to have part of a row inside a list of rows to to animate downwards without moving the views vertically above it.
Here is a minimal example, showing what I mean:
import SwiftUI
struct ContentView: View {
#State var display = false
var body: some View {
List {
Button("Toggle") {
display.toggle()
}
Text("Text")
row
Text("Text")
}
.listStyle(.plain)
.animation(.linear, value: display)
}
var row: some View {
VStack {
Text("Title").bold()
if display {
Text("Lorem")
Text("ipsum")
Text("dolor")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.previewDevice(.init(rawValue: "iPhone 13 mini"))
}
}
The lorem ipsum block is supposed to animate into view without moving the Title text.
I imagine there's no way around GeometryReader here, but wanted to make sure. All suggestions are much appreciated 🙏

Why the List does not appear?

Why the presetsList does not appear? No errors were thrown though.
import SwiftUI
struct AddMessagePreset: View {
let presetsList = [
Preset(name: "preset text 1"),
Preset(name: "preset text 2"),
Preset(name: "preset text 3")
]
var body: some View {
List(presetsList) { singlePresetModel in
SinglePresetChild (presetModel: singlePresetModel)
}
}
}
import SwiftUI
struct Preset: Identifiable {
let id = UUID()
let name: String
}
struct SinglePresetChild: View {
var presetModel: Preset
var body: some View {
Text("Preset Name \(presetModel.name)")
}
}
UPDATE: To show a List inside another ScrollView (or List), you have to set a height on the inner list view:
struct Preview: View {
var body: some View {
ScrollView {
AddMessagePreset().frame(height: 200)
// more views ...
}
}
}
But let me advise against doing so. Having nested scroll areas can be very confusing for the user.
As discussed in the comments, your component code is fine. However, the way you integrate it into your app causes a problem. Apparently, nesting a List inside a ScrollView does not work properly (also see this thread).
List is already scrollable vertically, so you won't need the additional ScrollView:
struct Preview: View {
var body: some View {
VStack {
AddMessagePreset()
}
}
}
P.S.: If you only want to show AddMessagePreset and won't add another sibling view, you can remove the wrapping VStack; or even show AddMessagePreset as the main view, without any wrapper.

SwiftUI: Remove Space above Navigation Bar

I have a simple view hierarchy between two views in SwiftUI.
MainView: This is the top level screen
import SwiftUI
struct MainView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: SearchView()) {
Text("Search")
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
SearchView:
import SwiftUI
struct SearchView: View {
var body: some View {
Text("Hello, World!")
}
}
I don't want a navigation bar on my main view, but I do want a "back" button on the Search view. This is how the Search view looks:
I don't want the space above the back button - where is that coming from?
I inspected the view hierarchy and it seems the view has TWO UINavigationBar objects. If I hide the navigation bar inside the Search View, the back button goes but the space still remains.
How do I get rid of this unwanted space above the Back button?

SwiftUI NavigationLink

I'm working on a SwiftUI practice app and I ran into an issue with the NavigationView/NavigationLink. I am currently using the Metropolitan Museum of Art API and I wanted to make a list of departments that segues to another list of objects in that department, then that list segues to the object's information. Currently the NavigationView/NavigationLink setup I have is creating multiple NavigationViews and is resulting in multiple back buttons/navigation bars. Is there a way to have the new NavigationView replace the old one or have them work in line with one another? The only way I know how to create a segue in SwiftUI is through a NavigationView/NavigationLink but creating it twice seems to be the wrong way to go about things. I have a screen shot of the current state of my app.
App Image
This is my code at the moment.
struct ContentView: View {
#ObservedObject var model = DepartmentListViewModel()
var body: some View {
NavigationView {
List {
ForEach(model.departments, id: \.self) { department in
NavigationLink(destination: DetailView(viewModel: DetailListViewModel(selectedDepartment: department))) {
Text(department.displayName)
}
}
}
.navigationBarTitle("Departments")
}
}
}
struct DetailView: View {
#ObservedObject var viewModel: DetailListViewModel
init(viewModel: DetailListViewModel) {
self.viewModel = viewModel
}
var body: some View {
NavigationView {
List {
ForEach(viewModel.objects, id: \.self) { object in
NavigationLink(destination: ObjectView(viewModel: ObjectListViewModel(selectedObject: object))) {
Text(String(object))
}
}
}
.navigationBarTitle("ObjectIDs")
}
}
}
You don't need NavigationView in your DetailView anymore, the first one handle it

SwiftUI - Picker not working when inside a Form (iPad split view)

I'm using Xcode 11 GM
The hierarchy I have is:
List > Form (Picker)
This is the code for List:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView{
List {
NavigationLink(destination: FormView())
{
Text("Item 1")
}
}
.navigationBarTitle("List")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
And this is the code for the Form:
import SwiftUI
struct FormView: View {
var body: some View {
Form {
Picker(selection: .constant(1), label: Text("Picker")) {
Text("1").tag(1)
Text("2").tag(2)
}
}
.navigationBarTitle("Form")
}
}
struct FormView_Previews: PreviewProvider {
static var previews: some View {
FormView()
}
}
The problem is:
When I build on iPad split view, tap to select works as expected:
But, when inside tags I cannot select them, nor it will go back to form view:
On iPhone, it works fine...
Is this a known bug?
Cheers to all
In my experience, it seems that the picker cells expect the user to tap on the Text elements themselves.
I don't know why. I think it's weird, too, and probably a bug. Not sure Apple knows about it yet. I sure haven't filed a radar.
To confirm this, try testing with longer text in the picker items.
What I normally do is implement a simple picker myself (not that hard, just a List and some items) and implement the items as Buttons. (If it changes the color on me, I change it back using .foregroundColor(.primary)). What's nice about this is that a Button inside a Form or a List renders as the table view cell we're used to, with the same highlighting interaction we all know and love!