Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I feel like I'm declaring so many functions to use inside my main View.
So for example instead of coding:
Button(self.title) {
// describing actions by hardcoding
}
Button(self.title) {
// using aforedefined functions
self.btnClicked()
self.presentPopover = true
}
What is a good practice? What is more SwiftUI native? Should I consider some other ways?
My personal preference is to keep body minimal, to achieve this you better to use functions.
Even further;
func buttonAction() { }
// If no extra action needed, you can pass reference to your function
Button("Title", action: action)
// If you use viewModel
Button("Title", action: viewModel.action)
Here is a bonus advice to keep body small as possible;
Transfer your Text, Button or any other View to var or func to see something similar below;
// MARK: - Image
private var image: some View {
Image("")..
}
// MARK: Title
private var titleText: some View { .. }
// and so on..
var body: View {
image
titleText
descriptionText
actionButton
}
Related
During Xcode UI test, I found my custom view's (MenuViewButton) is un-hittable in a test, I could found it but cannot touch it. In debug , when I po isHittable in console, it returns false. However I'm not sure if this is the correct behavior.
Per this thread XCUIElement exists, but is not hittable said, isHittable is default false for custom view element, and default true for UIKit standard view. But I don't know if it is the same behavior in SwiftUI.
Since the way someView.isAccessibilityElement = true is not possible in SwiftUI. My question is how could I let my custom view became hittable? Then it could be tapped in a test.
private var aView: some View {
MenuViewButton(
image: Image("an image name"),
text: Text("a string")
)
.accessibility(identifier: "xxx name")
}
I also use force tap with coordinate in case tap() is not working, but to give a offset of normalizedOffset didn't fix the problem in all places, it means some un-hittable element could be tapped, that is great but some others still not.
So may I know where normalizedOffset is start, from the middle of frame to give the offset or the top left?
func forceTapElement(timeout: TimeInterval) {
if !self.waitForExistence(timeout: timeout) {
return
}
if self.isHittable {
self.tap()
} else {
let coordinate: XCUICoordinate = self.coordinate(withNormalizedOffset: CGVector(dx: 0.1, dy: 0.0))
coordinate.tap()
}
}
Add https://github.com/devexperts/screenobject as a dependency
Use .tapUnhittable() instead of .tap() for this particular view. It gets the coordinates and taps using them
I have the same situation and am looking for answers. What has worked for me was to use:
let coordinate = element.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5))
Still this seems like workaround for a real problem. One other strange thing is that i do not have this problem on iOS15.0 simulator, only for later versions. Currently trying with iOS15.2
One more thing I've tried is to add
.accessibilityElement(children: .combine)
and specificly telling it's a button with
.accessibility(addTraits: .isButton)
But this doesn't solve the problem.
Seems that isAccessibilityElement would be an answer here, but SwiftUI doesn't seem to have such.
All
Something is wired when use swiftui.
object is not update in closure whick assign on second view when navigate back.
code like this:
NavigationLink(destination:
DiscountsView(selectFunc: { (discount: DessertDiscount) in
self.collection.discount = DiscountEntity(discount: discount)
self.testDesc = discount.name
})
) {
Text("优惠方案:\(self.collection.discount.name)")
.font(ViewApperance.shared.font)
.foregroundColor(ViewApperance.shared.fontColor)
}
)
The data Of collection not update, but testDesc update work, is anyone know what happen in this case, and what is the priciple of Object update in Swift?
I have a formatted SiwftUI TextField and I want it to format when editing changes. What would be the correct way of doing that?
TextField("", value: $binding, formatter: $formatter,
onEditingChanged: { (editingChanged) in
//How to force formatting here?
},
onCommit: {
//Here formatting happens.
})
OnEditing closure is called when the editing mode of the TextField changes. So it would be called with true when you start editing and called with false when you end (and so would onCommit at the end unless you cancel, but need to check).
I don't think that's what you want. If you want to format while the user is changing the text in the TextField, try something like this:
TextField("text", text: $text).padding()
.onReceive(text.publisher) { (c) in
print("Got \(c)")
self.text = self.text.uppercased()
}
But, keep in mind when you apply the formatting to $text, the new formatted version will be published, triggering a second closure call. This double call may or may not be an issue depending on the formatting you want and how text is used elsewhere.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am trying to develop a form that allows users to define variables and use conditions iterations. The form will then pass the texts to the application, where they will be translated and become part of the coding. It's like a template that allows a user to write relatively complex functions. It is more than a calculator because it allows for some programming within the structure. I am using Qt.
I was wondering if this is doable. If so what type of forms and the logic I should use.
It is possible to do it, but the complexity varies depending on where you are aiming at.
For QML it will be quite easy, because it is an interpreted language, it doesn't require compilation, so you can write some code in a text field and execute it.
For C++ it is not as easy, as it is a compiled language, you will have to bundle a compiler with the application, compile the code to a shared library, load it, get a pointer to the function and run it.
In both cases you will need to have a defined interface of the format of data input and linkage to already existing program objects. Based on the wording of your question, your skills may not be quite up to the task yet.
Here is a simple example how to do it in QML:
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
id: main
visible: true
width: 500
height: 300
property int appData : 0
Column {
spacing: 5
Text {
text: "addData is " + appData
}
TextInput {
id: code
width: 500
height: 200
Rectangle {
anchors.fill: parent
border.color: "black"
border.width: 1
z: -1
}
}
Button {
text: "execute"
onClicked: {
var obj = Qt.createQmlObject('import QtQuick 2.0; QtObject { function foo(app) { ' + code.text + ' } }', main)
if (obj) {
obj.foo(main)
obj.destroy()
}
}
}
}
}
Then you can try out executing different statements, as long as they are valid, for example:
app.appData = 5;
app.appData--;
console.log(app.appData);
app.width = 300;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have an MFC program that is sort of like a text editor: http://www.dogdaysrpg.com/screen.png
What I want is to get the filename of the current working tab as a string. So for example, in the picture above, the string would be "Emergence1".
How do I get the filename used on the active tab?
Getting the title for a specific view is pretty simple: GetParentFrame()->GetTitle().
If you don't know which view is currently selected, finding that is actually a little trickier. There's an OnActivateView that's called when a view is activated or deactivated. You'll need to add an overload of that to keep track of which one was most recently activated. Then to find it, you'll enumerate your views (with your document's GetFirstViewPosition, GetNextView) to find the one that's active.
This is how I solved the problem.
I needed to get the title of the current active document.
In order to retrieve the current active document, use the following code:
CDocument * CEmergenceView::GetDoc()
{
CMDIChildWnd * pChild =
((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();
if ( !pChild )
return NULL;
CDocument * pDoc = pChild->GetActiveDocument();
if ( !pDoc )
return NULL;
// Fail if doc is of wrong kind
if ( ! pDoc->IsKindOf( RUNTIME_CLASS(CDocument) ) )
return NULL;
return (CDocument *) pDoc;
}
Then when you retrieve the document, call GetTtile, i.e:
CDocument * currentDoc = GetDoc();
CString title = currentDoc->GetTitle();