How to get row index in SwiftUI List?
Using .indices() is not a workaround, it is a proper way of doing it.
Alternatively, you can also use the code in the release notes for an indexed() array:
struct ContentView: View {
var persons = ["Boris", "Anna", "Tom"]
var body: some View {
VStack {
List(persons.indexed(), id: \.1.self) { idx, person in
Text("\(idx) - \(person)")
}
}
}
}
// This is taken from the Release Notes, with a typo correction, marked below
struct IndexedCollection<Base: RandomAccessCollection>: RandomAccessCollection {
typealias Index = Base.Index
typealias Element = (index: Index, element: Base.Element)
let base: Base
var startIndex: Index { base.startIndex }
// corrected typo: base.endIndex, instead of base.startIndex
var endIndex: Index { base.endIndex }
func index(after i: Index) -> Index {
base.index(after: i)
}
func index(before i: Index) -> Index {
base.index(before: i)
}
func index(_ i: Index, offsetBy distance: Int) -> Index {
base.index(i, offsetBy: distance)
}
subscript(position: Index) -> Element {
(index: position, element: base[position])
}
}
extension RandomAccessCollection {
func indexed() -> IndexedCollection<Self> {
IndexedCollection(base: self)
}
}
How to get the index of the element in the List in SwiftUI when the List is populated with the array?
This can be done using using .enumerated
. For your MenuItem
values it will be as follows
List {
ForEach(Array(menuItems.enumerated()), id: \.1.id) { (index, textItem) in
// do with `index` anything needed here
Text(textItem.text)
}
}
How to get on screen rows from List in SwiftUI?
You can use onAppear and onDisappear functions to maintain a list of visible rows and then use these to find a visible index.
struct ContentView: View {
let rows = (Unicode.Scalar("A").value...Unicode.Scalar("Z").value)
.map { String(Unicode.Scalar($0)!) }
@State var visibleRows: Set<String> = []
var body: some View {
List(rows, id: \.self) { row in
HStack {
Text(row)
.padding(40)
.onAppear { self.visibleRows.insert(row) }
.onDisappear { self.visibleRows.remove(row) }
}
Spacer()
Text(self.getVisibleIndex(for: row)?.description ?? "")
}
}
func getVisibleIndex(for row: String) -> Int? {
visibleRows.sorted().firstIndex(of: row)
}
}
How to get the index of a dynamic List / ForEach bindable element (new Xcode 13's syntax)?
You can build wrapper by yourself:
struct ListIndexed<Content: View>: View {
let list: List<Never, Content>
init<Data: MutableCollection&RandomAccessCollection, RowContent: View>(
_ data: Binding<Data>,
@ViewBuilder rowContent: @escaping (Data.Index, Binding<Data.Element>) -> RowContent
) where Content == ForEach<[(Data.Index, Data.Element)], Data.Element.ID, RowContent>,
Data.Element : Identifiable,
Data.Index : Hashable
{
list = List {
ForEach(
Array(zip(data.wrappedValue.indices, data.wrappedValue)),
id: \.1.id
) { i, _ in
rowContent(i, Binding(get: { data.wrappedValue[i] }, set: { data.wrappedValue[i] = $0 }))
}
}
}
var body: some View {
list
}
}
Usage:
ListIndexed($items) { i, $item in
HStack {
Text("Index \(i)")
TextField("", text: $item.text)
}
}
SwiftUI - How to get the selected index of a list when you have a search?
The solution by Aperi is not good, because the only elements tappable will be the texts, not the cells.
The correct answer is to wrap the Text
element as a view of a Button, like shown on this video...
Button(action: {
// do something()
}) {
Text(item.term!)
}
Get index number of CoreData at List in SwiftUI
Here is a possible approach
ForEach(self.toDoItems.indices, id: \.self) { index in
HStack{
Text("\(toDoItems[index].title!)")
}.onTapGesture {
print("Print current Index: \(index)")
}
}
Get index in ForEach in SwiftUI
This works for me:
Using Range and Count
struct ContentView: View {
@State private var array = [1, 1, 2]
func doSomething(index: Int) {
self.array = [1, 2, 3]
}
var body: some View {
ForEach(0..<array.count) { i in
Text("\(self.array[i])")
.onTapGesture { self.doSomething(index: i) }
}
}
}
Using Array's Indices
The indices
property is a range of numbers.
struct ContentView: View {
@State private var array = [1, 1, 2]
func doSomething(index: Int) {
self.array = [1, 2, 3]
}
var body: some View {
ForEach(array.indices) { i in
Text("\(self.array[i])")
.onTapGesture { self.doSomething(index: i) }
}
}
}
How to get the index of a deleted row from a list in SwiftUI?
If you remove by-one, then the following give you index of deleted row
func delete(at offsets: IndexSet) {
self.symptoms.remove(atOffsets: offsets)
// here I want to make the HTTP request
let index = offsets[offsets.startIndex]
// ... use index in HTTP request
}
SwiftUI How do I record the index of the grid item that is currently being displayed on CollectionView?
Found a super easy solution to this problem. This does the snap to item and passes an index, just like an old collection view would.
I added an @State var selection: Int = 0 to the ContentView, and "selection" Bindings to the map and results view.
Then I replaced the Collection View Controller section with this:
TabView(selection: $selection) {
ForEach(Array(zip(results.indices, results)), id: \.0) { index, result in
ResultCardView(place: result[0]).tag(index)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
It does exactly what I want, and took me five minutes to implement.
I found that solution here: https://swiftwithmajid.com/2020/09/16/tabs-and-pages-in-swiftui/
Related Topics
How to Update Swift from 3.1 to 3.2, But Not to 4.0
Cast to a Metatype Type in Swift
How Does Anyobject Conform to Nsobjectprotocol
Why Do I Need to Declare an Optional Value as Nil Explicitly in Struct - Swift
Why 'There Cannot Be More Than One Conformance, Even with Different Conditional Bounds'
Swift Extension for Selected Class Instance
How Do Closures Capture Values from Previous Calls
Hex String to Character in Pure Swift
How to Use JSON Arrays with Alamofire Parameters
Clipped Image Calls Tapaction Outside Frame
Reusing Security Scoped Bookmark
Calling Getsectiondata from Swift
Swift Bindings Won't Work Xcode 6 Beta 5
In Swift, Does Resetting the Property Inside Didset Trigger Another Didset