Creating Menu in SwiftUI - receive output message of [UILog] Called -[UIContextMenuInteraction updateVisibleMenuWithBlock:] - menu

I'm attempting to create a pull down menu in SwiftUI , the menu seems to be fully visible on the device/simulator and I can interact with it but I get the following message:
[UILog] Called -[UIContextMenuInteraction updateVisibleMenuWithBlock:] while no context menu is visible. This won't do anything.
Can anyone suggest a solution or help me understand the problem ? XCode Version 12.2 beta 4
struct AardvarkQuantity: View {
var body: some View {
VStack{
Menu(content: {
ForEach((1...5), id: \.self) {
Text("\($0)")
.font(Font.fontSFProText(size: 9))
}
}, label: {
Text("Number of Aardvarks")
.font(Font.fontSFProText(size: 12))
.foregroundColor(ColorManager.itemRowLabelText)
})
}
}
}

As Andrew and pawello2222 both confirmed, the error message appears to be a log warning and code appears to be working
I ended up using the solution listed here.
Although I'm still not clear on how I should respond to the warning.

Related

How to mix your own undo and webContents.undo() in Electron?

I want to handle my own undo/redo menu commands and at the same time still support the Electron built-in undo/redo of the webContents object when it is relevant, for example when the user is focused on a text input element.
This answer seems like a good start, but it is incomplete as it does not address the root question, which is how to mix the two things.
Here is how the ideal code would look like when defining the menu item:
{
label: 'Undo',
accelerator: 'CmdOrCtrl+Z',
click: function(menuItem, focusedWin) {
if (*** focusedWin.webContents thinks it can handle it ***) {
focusedWin.webContents.undo();
} else {
// Run my own code
}
}
}
The one dollar question is: how do I code the "if focusedWin.webContents thinks it can handle it" test?
I found a solution to my problem. It's not elegant, but it works. The idea is that the built-in Edit menus such as undo/redo/cut/copy/paste/delete/etc. should be managed by the webContents object only when the user is focused on an input or textarea element.
So in my index.html file, I send a message to the Main process when there is a focus or a blur event on input elements. This sets a global variable (yuck!) on the main process side which is used to make the decision between letting webContents do its job or doing it ourselves.
In index.html (I use jQuery and the great messaging system described in this other thread):
//-- Tell the main process if the preset Edit menus should be activated or not.
// Typically we active it only when the active item has text input
$('input').focus(() => window.api.send("menus:edit-buildin", { turnItOn: true }));
$('input').blur(() => window.api.send("menus:edit-buildin", { turnItOn: false }));
In main.js:
// This is a global :-( to track if we should enable and use
// the preset Edit menus: undo/redo/cut/copy/paste/delete
var menusEditPreset = false;
// Listen to the renderer
ipcMain.on("menus:edit-buildin", (event, { turnItOn }) => {
menusEditPreset = turnItOn;
});
// ... and in the menu definition:
{
id: 'undo',
label: 'Undo',
accelerator: 'CmdOrCtrl+Z',
click: (event, focusedWindow, focusedWebContents) => {
if (menusEditPreset) {
focusedWindow.webContents.undo();
} else {
console.log("My own undo !");
}
}
},

Why does using FetchedResults work for Text and not TextField? SwiftUI, CoreData/ FetchRequest

I am getting CoreData properties from a FetchRequest and want to use it to pre-populate a text field (a user's Email).
Here is the FetchRequest
#FetchRequest(
entity: Account.entity(),
sortDescriptors:[
NSSortDescriptor(keyPath: \Account.id, ascending: true)
]
)var accounts: FetchedResults<Account>
Note I have all of the proper persistant container and #environment stuff set up to use #FetchRequest like this.
Then in my View stack I have:
var body: some View{
ZStack {
Form {
Section(header: Text("EMAIL")) {
ForEach(accounts, id: \.self) {account in
TextField("Email", text:account.email) // This is where I get an error (see error below)
}
}
}
Error is : Cannot convert value of type 'String' to expected argument type 'Binding<String>'
However is I simply list accounts in a textfield it works. Like so:
var body: some View{
ZStack {
Form {
List(accounts, id: \.self) { account in
Text(account.email ?? "Unknown")
}
}
}
Why does the second code that uses List not give me the same error?
I thought it had something to do with the ?? operator but after research I realized that it perfectly fine to do given that email in my coredata object is String?.
Now my thought is that I am getting this error here because TextField needs a Binding wrapper? If that is true I'm not sure how to get this to work. All I want to do is have this TextField pre-populated with the single email record the FetchRequest retrieves from my Account Core Data object.
Thanks.
Edit: I want to add that I have found this post https://www.hackingwithswift.com/quick-start/swiftui/how-to-fix-cannot-convert-value-of-type-string-to-expected-argument-type-binding-string
and now I think what I need to do is store this account.email result into a State variable. My question still remains however, I'm not sure how to do this as I am looking for clean way to do it right in the view stack here. Thanks again.
TextField needs a binding to a string variable. Account is and ObservableObject, like all NSManagedObjects, so if you refactor your TextField into a separate View you could do this:
Form {
Section(header: Text("EMAIL")) {
ForEach(accounts, id: \.self) { account in
Row(account: account)
}
}
}
...
struct Row: View {
#ObservedObject var account: Account
var body: some View {
TextField("Email", text: $account.email)
}
}
Note the $account.email — the $ turns this into a binding.
Unfortunately, this new code also fails, because email is a String? (i.e., it can be nil) but TextField doesn’t allow nil. Thankfully that’s not too hard to fix, because we can define a custom Binding like so:
struct Row: View {
#ObservedObject var account: Account
var email: Binding<String> {
Binding<String>(get: {
if let email = account.email {
return email
} else {
return "Unknown"
}
},
set: { account.email = $0 })
}
var body: some View {
TextField("Email", text: email)
}
}
Notice we don’t have a $ this time, because email is itself a Binding.
This answer details getting a CoreData request into a #State variable:
Update State-variable Whenever CoreData is Updated in SwiftUI
What you'll end up with is something like this:
#State var text = ""
In your view (maybe attached to your ZStack) an onReceive property that tells you when you have new CoreData to look at:
ZStack {
...
}.onReceive(accounts.publisher, perform: { _ in
//you can reference self.accounts at this point
//grab the index you want and set self.text equal to it
})
However, you'll have to do some clever stuff to make sure setting it the first time and then probably not modifying it again once the user starts typing.
This could also get complicated by the fact that you're in a list and have multiple accounts -- at this point, I may split every list item out into its own view with a separate #State variable.
Keep in mind, you can also write custom bindings like this:
Binding<String>(get: {
//return a value from your CoreData model
}, set: { newValue in })
But unless you get more clever with how you're returning in the get section, the user won't be able to edit the test. You could shadow it with another #State variable behind the scenes, too.
Finally, here's a thread on the Apple Developer forums that gets even more in-depth about possible ways to address this: https://developer.apple.com/forums/thread/128195

Index Beyond Bounds / EXC_BAD_ACCESS upon Core Data Delete SwiftUI

I'm getting a Index Beyond Bounds error and a Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) when trying to delete a Core Data index in SwiftUI.
Basically, I have a Core Data entity (Dates), containing only a date attribute (Constraint - String). This has a one-to-many relationship with my Records Entity. I am trying to display a list of all date's I have. Displaying is fine, but upon trying to delete it, my app crashes.
My View currently looks as following:
import SwiftUI
struct Settings: View {
#Environment(\.managedObjectContext) var managedObjectContext
#FetchRequest(entity: Dates.entity(), sortDescriptors: []) var dates: FetchedResults<Dates>
var body: some View {
VStack {
List{
ForEach(dates, id: \.self) { day in
Text("\(day.wrappedDate)")
}.onDelete { (indexSet) in
let dateToDelete = self.dates[indexSet.first!]
self.managedObjectContext.delete(dateToDelete)
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
}
}
}
}
}
I've broken my view down to the bare minimum to see if that would help, but unfortunately not.
When trying to delete. The error I get in the output is:
2020-04-29 16:08:23.980755+0300 TESTTEST[28270:2245700] [General] *** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray
If I have say 9 dates, it would say index 8 beyond bounds [0 .. 7], so it's not necessarily related to an empty Array.
Further output is:
=== AttributeGraph: cycle detected through attribute X ===
a bunch of times, followed by:
Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
on my AppDelegate.
Could the issue be in generating the view - rather than the delete?
Please be aware that I'm a self-taught, absolute Noob when it comes to coding, so I might be missing something obvious here. Any help on getting to the answer myself in the form of instructions would also be greatly appreciated (so I can learn how to fix this).
EDIT:
I think I found out what's causing the issue. In another view I'm also generating a list of all dates , where I apply an index on Dates. Will amend code now to see if this fixes it....
TBC!
In a separate view I was calling a list of dates in the following way:
ForEach(0 ..< self.dates.count, id: \.self) { index in
Text("\(self.dates[index].date)")
}
Deleting one of the Date entities, would mess up the indices presented in this view. Changing this structure to the below fixed the issue:
ForEach(self.dates, id: \.self) { day in
Text("\(day.date)")
}

How to minimize a prime ng dialog?

I would like to know how can I minimize a prime ng dialog box. I read this but it is not working in Angular 7.
Also, as per their site here, the property minimizable is not present
Also I am using the dialogService of primeng. Is there any way that I can minimize the dialog and continue working.
Demo code for reference where I am using dialog service to open the angular component:
showPopup(header: string, groupName: string, controlName: string) {
const dialogRef = this.dialogService.open(StandardParagrahPopupComponent, {
header: header,
width: '60%',
closable: true,
data: {
groupName: groupName
}
});
dialogRef.onClose.subscribe(comments =>
this.onPopupClose(comments, controlName)
);
}
Minimize is not working in PrimeNG for Angular.
It is only working in Primefaces for JavaServletFaces.
The first link you provides leads to Primefaces Showcase, the second to PrimeNG showcase. So it is correct that on the second link you can´t find the minimize feature.

QML Strings in BlackBerry Cascades

I am trying to build a custom button in newest BlackBerry 10 platform.
The button should change background image when it is clicked and then change it back when it is clicked the second time.
The button logic is fairly simple: once clicked, I check for the type of image currently in the button and change the image source.
I started with a basic QML custom control which looks like this (stripped of labels and other unimportant things):
import bb.cascades 1.0
Container
{
id: root
layout: DockLayout
{
}
function clickMe()
{
var source = myImage.defaultImageSource.toString();
console.log(source);
if (source.endsWith("image.png"))
{
myImage.defaultImageSource = "asset:///images/image_pushed.png";
}
else
{
myImage.defaultImageSource = "asset:///images/image.png";
}
}
ImageButton
{
id: myImage
defaultImageSource: "asset:///images/image.png"
}
onCreationCompleted:
{
myImage.clicked.connect(root.clickMe);
}
}
ImageButton click event is connected to JavaScript function clickMe. The function fires and the URL is logged to console correctly.
The problem is the IF clause, because the image_pushed.png is never set. Why is this the problem and how can I implement this button?
I am looking around for a only QML solution for this problem and I found this information:
the defaultImageSource property is of type QUrl, which does contain
toString() method.
toString() method returns QString, which indeed has function endsWith.
my QML reference: http://qt-project.org/doc/qt-4.8/qstring.html#endsWith
Thanks.
Within QML QString instances appear to be a normal JavaScript strings. This mapping is done automatically. And Javascript strings don't have a endsWith method. You can use the search method with an regular expression to achieve the same.
if (source.search(/image\.png$/ !== -1) { /* ... */ }
I think you can create more simple way by using property
for example:
Control{
id : myControl
property bool state
ImageButton{
defaultImageSource : state ? "firstImageAsset.png" : "secondImageAsset.png"
onClick :{
myControl.state = !myControl.state
}
}
}

Resources