I am working on table view which looks like this:
I looked on the internet but all information is about a search bar and I do not want a search bar but only the two options - vaccinated and not vaccinated. How could I make so that I can filter the table by them?
You should have 2 arrays
var allData = [Model]()
var filteredData = [Model]()
And
struct Model {
var vaccinated:Bool
}
when the button is clicked do
filteredData = allData.filter { $0.vaccinated } // or !$0.vaccinated for the second option
tableView.reloadData()
Related
I'm currently working on a project that uses SwiftUI. I was trying to use List to display a list of let's say 10 items.
Does List supports reusability just like the UITableview?
I went through multiple posts and all of them says that List supports reusability: Does the List in SwiftUI reuse cells similar to UITableView?
But the memory map of the project says something else. All the Views in the List are created at once and not reused.
Edit
Here is how I created the List:
List {
Section(header: TableHeader()) {
ForEach(0..<10) {_ in
TableRow()
}
}
}
TableHeader and TableRow are the custom views created.
List actually provides same technique as UITableView for reusable identifier. Your code make it like a scroll view.
The proper way to do is providing items as iterating data.
struct Item: Identifiable {
var id = UUID().uuidString
var name: String
}
#State private var items = (1...1000).map { Item(name: "Item \($0)") }
...
List(items) {
Text($0.name)
}
View hierarchy debugger shows only 17 rows in memory
I've search result on View A. I've a filter options on search result. When suer clicks on filter view A it takes him to view B which lists all the filter options. Clicking on filters on B will take user to View C which shows selection for each filter. When user selects filters on view C I want to pass it back to A so that when user goes back to view A, after selecting filters, result data on A is updated after applying selected filter.
How to do that in any other simplest way possible?
There are many ways. I will share the easiest. Create a modal struct, update its value from view controller C and then use it in A.
struct StudentData {
static var name = ""
static var address = ""
}
In View Controller C, update the values
StudentData.name = "your name"
StudentData.address = "your address"
In View Controller A,
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
nameField.text = StudentData.name
addressField.text = StudentData.address
}
I have tableview where I need to show few sections. You should imagine this table like a playlist of your songs. In the top first section I need to display a cell with button which will add more songs to the playlist and other sections of tableview are header titles of Music category (like pop, rock and etc). Each of these sections contains cells which are songs names.
I have an array of songs called like this: var songsGroups = [SongGroup]. Which is actually my datasource.
SongGroup contains few properties:
var categoryName: String
var songs: [Songs]
But the problem appears on the next level. I every time need to check indexPath.section and do like this:
if indexPath.section == 0 {
// this is a section for ADD NEW SONG BUTTON cell no need in header title as there is no data repression only static text on the cell.
} else {
var musicCategoryName = songsGroups[indexPath.seciton - 1]. categoryName
headerTitle.title = musicCategoryName
}
As you see my code became magical by adding this cool -1 magical number. Which I replay don't love at all.
As an idea for sure I can try to combine my ADD NEW SONG BUTTON section (by adding some additional object) with songsGroups array and create NSArray for this purposes. Like in Objective-C as you remember. So then my datasource array will looks like this:
some NSArray = ["empty data for first cell", songsGroups[0], songsGroups[1]... etc]
So then there is no need to check any sections we can trust our array to build everything and even if I will add more empty data cells there is no need for me to handle my code via if block and adding tons of magical numbers.
But the issue I see here that we don't use explicit types of array and it's upset.
So maybe you know more beautiful solutions how to resolve my issue.
You can introduce a helper enum:
enum Section {
case empty
case songCategory(categoryName: String, songs: [String])
}
Your data source would then look something like this:
let datasource: [Section] = [.empty, .songCategory(categoryName: "Category1", songs: ["Song 1", "Song2"])]
So now you can use pattern matching to fill the table view:
let section = datasource[indexPath.section]
if case let .songCategory(categoryName, songs) = section {
headerTitle.title = categoryName
} else {
// this is a section for ADD NEW SONG BUTTON cell no need in header title as there is no data repression only static text on the cell.
}
I am not sure if I understand you right. But is seems to me that you want to display
1) something that lets the user add a new song by tapping a button, and
2) a table of songs, sectioned into groups.
If this is the case, why don’t you put the add new song button in the table header view, and all your song groups and songs in a 2-dim array used as your dataSource?
Using xcode 9.4, Swift 4 and ios 11, I want to select an item from a collection view screen that goes to a table view screen. On the table view screen, I have a series of arrays and, depending on what I've chosen on the collection view screen, I want to display a specific array on the table view screen.
I've already set up the prepareForSegue function on the collection view screen that references a var on the table view, but I'm a bit stuck on the "select an array" bit. I'm pretty sure it involves an if statement, but I'm not sure how or where to put this if statement.
Any help would be greatly appreciated.
Here's the if statement that I made (I don't know if its correct):
if cellItem == "jeans" {
tableArray.append(jeanArray[])
} else if cellItem == "skirts" {
tableArray.append(skirtArray[])
}
Then in the functions for the table set up, I've referenced tableArray.
There are a number of ways you can do this, I'm guessing the arrays contain similar information (guessing from jeans and skirts its clothing).
I would have a single value for determining which product type is to be displayed, then you have a few options available....
enum TableMode {
case jeans, skirts, trousers, hats
}
The multiple products array way (not recommended)
class TableViewController: UITableViewController {
var tableMode: TableMode
func tableView(UITableView, numberOfRowsInSection: Int) -> Int {
switch tableMode {
case .jeans:
return jeansArray.count
/// and so on...
}
}
}
Another option would be to have a single array that will be used, just fill it with the correct data: (best method)
// the int value could be the category ID from your API
enum TableMode: Int {
case jeans = 13
case skirts = 2
trousers = 4
hats = 19
}
class TableViewController: UITableViewController {
var tableMode: TableMode
var products: [Products]()
override viewDidLoad() {
super.viewDidLoad()
// fetch all data from api/database where categoryId = .tableMode value
self.products = coreDataFetchResult
self.tableView.reloadData()
}
Last idea, fetch all products and just filter it as needed to show the current product type selection
class TableViewController: UITableViewController {
var tableMode: TableMode
var products: [Products]()
override viewDidLoad() {
super.viewDidLoad()
// fetch all data from core data
self.products = coreDataFetchResult.filter { $0.categoryId = self.tableMode }
self.tableView.reloadData()
}
The best option depends on where you are filling the arrays from. I wouldn't suggest having multiple arrays if you are only going to use one.
I have some code right now that gets what cells were selected. The following is my code for doing that:
if let selectedUserRows = self.tableView.indexPathsForSelectedRows {
self.groupUserArray.append(selectedUserRows)
for index in selectedUserRows {
let text = groupUserArray[index.row]
print(text)
}
}
The new error is saying that the index is out of range!
I was trying to use the logic for grabbing one selected cells text but it does not work. So I was wondering if anyone knew how to grab multiple selected cell's text?
Any help would be appreciated!
self.tableView.indexPathsForSelectedRows returns a [IndexPath]? so if you obtain an array of all the rows and sections of you selected rows. I suppose you are using some sort of collection to populate your tableView (in my example I will call it textArray: [String] ) so you can do something like that to get all the text you need:
if let selectedUserIndexes = self.tableView.indexPathsForSelectedRows {
for index in selectedUserIndexes {
let text = textArray[index.row]
}
}