Can I put an array into another array in swiftUI? - swiftui

I have an array of cards and want to put them into an array of decks. Users can make their own decks and creates cards within. I've finished making the flashcard part of the app and you can make one deck only.
NavigationView {
Section {
List(decks) { deck in
NavigationButton(destination: ContentView (deck: testDeck))
DecksRow(deck: testDeck)
}
}
} .navigationBarTitle(Text: "Rows")
}
I am new to swiftUI.

Related

SwiftUI make LazyGrid Item twice the size of other Items

I want to display a grid where one item takes twice the amount of space of the others.
Similar to this HTML Grid
Basically I want the last item Text("div4") to take up the space of two items. I do not want to use .fixed since it should take exactly twice the space of the other grids no matter the screen size.
If there is a way to archive this without LazyGrid, that is also fine with me ;)
Here is my current code:
let cols = [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())]
var body : some View {
LazyVGrid(columns: cols){
Text("div1")
Text("div2")
Text("div3")
Text("div4")
}
}
Since Swift does not support this. A solution would be to use a library like: ExyteGrid!
var body : some View {
Grid(tracks: [.fr(1),.fr(1),.fr(1),.fr(2)]){
Text("div1")
Text("div2")
Text("div3")
Text("div4")
}
}
https://cocoapods.org/pods/ExyteGrid

Delete row from Realm via SwiftUI occurs exception 'Object has been deleted or invalidated.'

I trying to delete row from SwiftUI list which load data from Realm DB, it's implemented like here:
struct MyView: View {
private let realm = try! Realm()
var body: some View {
List {
ForEach(realm.objects(MyModelDB.self)) { model in
MyRow(model: model)
}
}.onDelete { indexSet in
try? realm.write {
indexSet.forEach { index in
realm.delete(words[index])
}
}
}
}
}
}
}
but when I perform deleting, I receive an exception:
*** Terminating app due to uncaught exception 'RLMException', reason: 'Object has been deleted or invalidated.'
Whats wrong?
A couple of options are: delete the objects in reverse order OR delete all of the objects at once.
Here's why. Suppose you have three objects
a index 0
b index 1
c index 2
so the total count is 3 and your indexSet contains indexes 0 1 and 2.
If you were to iterate over that, there would be three loops, however, realm is live updating so if you delete the object at index 0, then only two indexes remain, so when it tries to perform the third loop, it will crash.
Deleting in reverse alleviates that issue as index 2 is deleted first, then index 1 and then index 0.
I would suggest gathering up the objects you want deleted into an array or list and then deleting them all at once without iterating
realm.delete(objects: Sequence>)
where Sequence would be an Array or List.

SwiftUI Make a list that shows only a certain amount of rows

I have recently started messing around with SwiftUI and so far it is great. I have however ecnountered a problem that I can't seem to find an answer to.
I am trying to create this design:
As you can see here is a tableview (a list) which rows have a smaller tableview (a list) inside them. The task was pretty simple while using IB, but with swiftUI I can't seem to find a way to limit the number of rows to only the amount I need or to manually set the lists height based on the number of rows (keep in mind those rows can also be variable in height).
My code so far only consist of creating the List and adding 2 test rows:
List {
OrderItemRow()
OrderItemRow()
}
But as you can see SwiftUI automatically stretches the List to fill all the available space. The effect:
If you know the height of your rows, this can be achieved like this:
List(self.arrayOfAllItemsInOrder(currentOrder)) { item in
OrderItemRow(currentOrder: order, item:item)
}
.environment(\.defaultMinListRowHeight, rowHeight)
.frame(height: self.arrayOfAllItemsInOrder.reduce(0) { i, _ in i + rowHeight })
This will calculate the full size of the list based on rowHeight and limit the frame's height.
Note that if the size of your row goes beyond rowHeight, the entire calculation will be messed up and you will probably be seeing half (or missing entire) cells.
I would suggest a List using a ForEach to show your orders and a nested ForEach to show items in an order. The key is to manage the Data being supplied to each ForEach to the number of items desired and also to construct appropriate Row Views for OrderHeaderRow, OrderItemRow, etc.
struct OrdersView: View {
var body: some View {
List {
Section(header: Text("Current Order")) {
OrderHeaderRow(order: currentOrder)
ForEach(self.arrayOfAllItemsInOrder(currentOrder)) { item in
OrderItemRow(currentOrder: order, item:item)
}
OrderTotalRow(order: order)
ActionButtonsRow(order:order)
}
Section(header: Text("Previous Orders")) {
ForEach(self.arrayOfAllPreviousOrders) { order in
OrderHeaderRow(order: order)
ForEach(self.arrayOfAllItemsInOrder(order)) { item in
OrderItemRow(order: order, item:item)
}
OrderTotalRow(order: order)
ActionButtonsRow(order:order)
}
}
}
}
}

PushBack() element from one Vector into another. Remove from originating Vector

Since This Post didn't exactly answer my question I'm going to start a new one.
I'm encoutering a problem when moving an element from one vector to another.
The originating vector is a simple deck of cards and the end vector is supposed to represent cards in the player's hand.
I'm using Hand.push_back(Deck.back()) to copy the "top" card and then Deck.pop_back() to remove it from the Deck vector.
Strangely though the next time I call the Draw Card function it "draws" the same card that should have been removed last turn.
I'm guessing it's a problem with resizing the vector? Should I try Deck.resize(Deck.size() - 1) after each pop_back()?
void Player::DrawStartingHand(int num)
{
for(int i = 0; i < num; i++)
{
Hand.push_back(Deck.back());
Deck.pop_back();
}
}
void Player::DrawCard()
{
std::cout<< "Drawing next card..." << std::endl;
if(Deck.size() >= 1)
{
//copy card from top of deck
//place at front of hand
Hand.push_back(Deck.back());
//remove care from top of deck
Deck.pop_back();
}
else
{
std::cout<< "No cards left to draw\n";
}
}
EDIT:: Each of the above functions are currently only called in one place a piece, and not under any extreme circumstances or anything weird. Just very basic, simple calls.

QTreeWidget not displaying first item in a QList

I'm trying to display items in a QList on a QTreeWidget but no matter how hard i tried i observe that always the first item in the List is not inserted on the treeWidget.
Please i need help. Below is my sample code
void Results::showResults (QList<Semester*>* sList){
for(int i=0; i<sList->count(); i++)
{
ui->treeWidget->addTopLevelItem(sList->at(i)->treeItem);
}
this->show ();
}
NB: every Semester item in the list has a treeItem member.