Can iterate through an array with forEach, but not with List - swift

I have an array of notes (viewModel.list) that I would like to display in a List. All notes conform to Identifiable.
When I use ForEach, all notes appear just fine:
ForEach(viewModel.list){ note in
NoteView(namespace:namespace, note: note)
}
But if I change this to a List no objects appear:
List(viewModel.list){ note in
NoteView(namespace:namespace, note: note)
}
The same thing happens if I embed the ForEach in a List
List{
ForEach(viewModel.list){ note in
NoteView(namespace:namespace, note: note)
}
}
I want to use a List because I would like to add a swipeAction to every NoteView which can only be used in Lists. Is there any reason this behavior is happening?
UPDATE: I have uploaded a reproducible example below and believe it has something to do with embedding the List in a ScrollView. If I remove the ScrollView, this code works fine, but nothing shows up with it.
import SwiftUI
struct Note: Identifiable {
var id = UUID()
var content: String = ""
}
var notes = [
Note(content: "Lorem ipsum dolor sit amet, consectet adipiscing elit. Condimentum quisque id vitae convallis dignissim pharetra nisl est creatus"),
Note(content: "Mauris ac tempor libero, non eleifend lectus. Mauris eu hendrerit nunc. Donec at ante mauris. Duis ac elit purus. Mauris ullamcorper mi."),
Note(content: "Lorem ipsum dolor sit amet, consectet adipiscing elit. Condimentum quisque id vitae convallis dignissim pharetra nisl est creatus"),
Note(content: "Mauris ac tempor libero, non eleifend lectus. Mauris eu hendrerit nunc. Donec at ante mauris. Duis ac elit purus. Mauris ullamcorper mi.")
]
struct ContentView: View {
var body: some View {
ScrollView {
List(notes){ note in
NoteView(note: note)
.padding(.bottom)
}
}
}
}
struct NoteView: View {
var note: Note = notes[0]
var body: some View {
Text(note.content)
}
}

List is not showing because List infer it size from its parent View. So when you embed it inside something like Scrollview that have dynamic height, it can't infer it size correctly.
Also List behaves like a UIScrollView (an arbitrarily long scrollable view of views).
So no need to wrap List inside scrollview.
struct ContentView: View {
var body: some View {
// ScrollView {
List(notes){ note in
NoteView(note: note)
.padding(.bottom)
}
// }
}
}

Just remove List from ScrollView - it is scrollable itself.
struct ContentView: View {
var body: some View {
List(notes){ note in
NoteView(note: note)
.padding(.bottom)
}
}
}
*the reason of the issue is that List wants to take parent size to expand, but ScrollView does not have own size and expects from content a size that needs to be scrolled, result is obvious - cycling conflict - to do not crash/hang in cycling SwiftUI breaks layout - output is empty.

Related

How to extract digits and string from a combined string and put them seperately into different list [duplicate]

I have a List that contains lottery numbers
List image
How can I separate number and text, and after that list them in the below list: for example:
List<String> n = ["ABC23", "21A23", "12A312","32141A"];
Thank you!
You can do it by using forEach like below:
List<String> n = ["23", "2123", "12312","32141"];
n.forEach((element) =>
print(element)
);
And to separate number and text you can use the following code:
const text = '''
Lorem Ipsum is simply dummy text of the 123.456 printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an 12:30 unknown printer took a galley of type and scrambled it to make a
23.4567
type specimen book. It has 445566 survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
''';
final intRegex = RegExp(r'\s+(\d+)\s+', multiLine: true);
final doubleRegex = RegExp(r'\s+(\d+\.\d+)\s+', multiLine: true);
final timeRegex = RegExp(r'\s+(\d{1,2}:\d{2})\s+', multiLine: true);
void main() {
print(intRegex.allMatches(text).map((m) => m.group(0)));
print(doubleRegex.allMatches(text).map((m) => m.group(0)));
print(timeRegex.allMatches(text).map((m) => m.group(0)));
}
Please refer to this link for more information.
To do something with each element:
List<String> n = ["23", "2123", "12312","32141"];
n.forEach((element) {
int number = int.parse(element);
...
}
);
To do create list of ints:
List<String> n = ["23", "2123", "12312","32141"];
final intList = n.map((element) => int.parse(element)).toList();

How do I make a column of 3 cards match in height in bootstrapVue?

I have a row with 3 columns containing cards, the b-card-text (text in the cards) is not equal in length thus making the cards differ in height. Question is how do I make the cards match in height?
Tried adding h-100 d-inline-block classes to the cards but no luck.
<b-row>
<b-col class md="4">
<b-card>
<b-card-text>Lorem Ipsum is simply dummy text of </b-card-text>
</b-card>
</b-col>
<b-col class md="4">
<b-card class="h-75 d-inline-block">
<b-card-text>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make
</b-card-text>
</b-card>
</b-col>
<b-col class md="4">
<b-card>
<b-card-text>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard
</b-card-text>
</b-card>
</b-col>
</b-row>
I expect the cards to be the same in height.
On the <b-row> add the class class="align-self-stretch", or to make it applicable to only md and up breakpoints: class="align-self-md-stretch". And then use the utility class h-100 on each <b-card>
Example: https://jsfiddle.net/ofcxrquz/
See:
https://bootstrap-vue.js.org/docs/reference/utility-classes
https://getbootstrap.com/docs/4.3/utilities/flex/#align-self

Display richtext on webview with smartface

I tried to run Webview richtext display with below code given in the referance document but it gives empty page.
Did something wrong on the code or just does not support webview rich text?
Pages.Page1.webView1 = new SMF.UI.WebView({
top : "5%",
left : "5%",
width : "90%",
height : "90%",
URL : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
});
Pages.Page1.add(Pages.Page1.webView1);
You should assign your rich text as HTML to the URL to display a rich text paragraph in a Webview.You can add as below:
Pages.Page1.webView1 = new SMF.UI.WebView({
top : "5%",
left : "5%",
width : "90%",
height : "90%",
URL : "<p>Lorem ipsum dolor sit amet, <strong>consectetur adipiscing elit.</strong><mark>Nummus in Croesi divitiis obscuratur,</mark> pars est tamen divitiarum. Utrum igitur tibi litteram videor an totas paginas commovere?</p>"
});
Pages.Page1.add(Pages.Page1.webView1);

How to set line height in Clutter.Text using Pango

I want to have a Clutter.Text displaying text with double line spacing using Gtk.Pango.
note : in css, we would use line-height: 200% I think.
I tried this code and it didn't work:
var text_actor = new Clutter.Text.with_text ("Roboto 10", "Long long text") ;
text_actor.width= SIDE_PANE_WIDTH ;
text_actor.get_layout ().set_spacing (2*Pango.SCALE) ;
Apparently, Clutter.Text keeps a cached version of the Pango.Layout
Is there a way to achieve this?
One way working around this by using CoglPango directly:
var t = new Clutter.Actor ();
t.set_size (300, 300);
// add some more text to see it
var text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, ...";
var layout = t.create_pango_layout (text);
layout.set_width (200);
layout.set_spacing (24 * Pango.SCALE);
t.paint.connect (() => {
Cogl.pango_render_layout (layout, 0, 0,
Cogl.Color.from_4ub(0, 0, 0, 255), 0);
});
edit this is indeed the solution. Based on this, here's the code that I used:
actor = new Text () ;
actor.width= SIDE_PANE_WIDTH ;
var text = "Some long text<b>Bold</b>" ;
var pango_layout = bio_actor.create_pango_layout ("");
pango_layout.set_markup (text, text.length) ;
pango_layout.set_spacing (2 * Pango.SCALE);
pango_layout.set_font_description (Pango.FontDescription.from_string ("Roboto 10")) ;
pango_layout.set_width (SIDE_PANE_WIDTH * Pango.SCALE);
bio_actor.paint.connect (() => {
Cogl.pango_render_layout (pango_layout, 0, 0, Cogl.Color.from_4ub(255, 255, 255, 255), 0);
});
int width;
int height ;
pango_layout.get_size (out width, out height) ;
actor.height = height / Pango.SCALE;
Yes, ClutterText caches the PangoLayout instance to avoid having to re-measure text every time it has to retrieve the preferred size. It actually caches the latest three instances of PangoLayout, because of the width-for-height/height-for-width geometry requests, but that's just an implementation detail.
Changing properties on the PangoLayout instance of ClutterText is also not going to result in updates to the ClutterText: you'd have to call clutter_actor_queue_redraw() afterwards, as the PangoLayout sits at a lower level than the actor in the scene graph.
In general, the ClutterText actor does not allow you to tweak the PangoLayout it creates; it's expected that the actor is in charge of creating an modifying the layout, and attempts at overriding that will result in either poor performance or undefined behaviour.
If you want to introduce a line spacing property then you'll have to file a bug against ClutterText — though that would mean that you'd have to wait until September for the next stable release of Clutter.
If you don't need all that ClutterText does, and you just want to display text, you could subclass ClutterActor and use clutter_actor_create_pango_layout() to create a PangoLayout that you can measure inside the overridden get_preferred_width(), get_preferred_height(), and allocate() virtual functions, and paint inside the overridden paint() virtual function.

How to get the list view row count in blackberry 10 cascades qml?

I need to get the no of rows in a list view blackberry 10 cascades qml? The list view data source model type is json. I have tried this
ListItem.initialized ? ListItem.view.dataModel.childCount(ListItem.indexPath) : 0
But its displaying only 0 even the list view row count is more than 1.
My code
dataModel: groupdatamodel
listItemComponents: [
ListItemComponent {
type: "header"
Container {
preferredWidth: 748
layout: DockLayout { }
Label {
text: "Title"
base: SystemDefaults.TextStyles.TitleText
fontWeight: FontWeight.Bold
}
}
Label {
id: subtitle
text: groupdatamodel.size() + "Items"
textStyle {
base: SystemDefaults.TextStyles.SmallText
fontWeight: FontWeight.Bold
}
}
]
Main.qml
import bb.cascades 1.0
import bb.data 1.0
Page {
content: Container {
Label {
text: "List View with json parsing"
}
ListView {
id: listViewDemo
dataModel: GroupDataModel {
grouping: ItemGrouping.None
}
listItemComponents: [
ListItemComponent {
type: "listItem"
StandardListItem {
title: ListItemData.ThumnailImage
description: ListItemData.CategoryID
}
}
]
function itemType(data, indexPath) {
return "listItem";
}
}
}
attachedObjects: [
DataSource {
id: serviceDataSource
source: "contacts.json"
type: DataSourceType.Json
onDataLoaded: {
listViewDemo.dataModel.clear();
listViewDemo.dataModel.insertList(data)
}
}
]
onCreationCompleted: {
serviceDataSource.load();
}
}
Contacts.json
[ {"CategoryID":"3","CategoryName":"News","CountryID":"1","Result":"OK"},
{"CategoryID":"4","CategoryName":"Daily Paper","CountryID":"1","Result":"OK"},{"CategoryID":"5","CategoryName":"Thanthi","CountryID":"1","Result":"OK"}, {"CategoryID":"1","CategoryName":"Newspaper","CountryID":"1","Result":"OK"},
{"CategoryID":"2","CategoryName":"Magazine","CountryID":"1","Result":"OK"}
]
main.cpp
add follwing lines in main file
#include <bb/data/DataSource>
#include <bb/data/JsonDataAccess>
Q_DECL_EXPORT int main(int argc, char **argv)
{
// We want to use DataSource in QML
bb::data::DataSource::registerQmlTypes();
4.FILENAME.PRO
LIBS += -lbbdata
DataModel::childCount(ListItem indexPath) returns the child count for the item in the list specified by indexPath, not the count of data items in the data model (and therefor available to the list). You need to interrogate the actual data model. For example GroupDataModel::size() returns the number of items in the GroupDataModel, similarly for QListDataModel.
I use this code in my project and it works fine:
console.log("pcs count" + pcsListModel.childCount(0));
Adding custom elements in label is not possible unless you use custom data model.
you can use:
your_groupdatamodel.size().toString();
or
your_groupdatamodel.childCount(0);
in javascript code.
J.