I am developing an AppKit application in MacOS with Swift.
Our application requires a complex, multi-windowed interface and must deliver a very fast, responsive experience.
As a performance test, I built a sample app that creates 3 windows programmatically, each containing 500 NSTextFields (with each text-field assigned 35 different properties).
Code flow: https://gist.github.com/Raunit-TW/5ac58ac9c6584f93e2ee201aa8118139
This takes around 77 milliseconds to render the windows - I need to find a way to reduce this time, as low as possible.
Thanks.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I want to understand what the recommended way is for string interoperability between swift and c++. Below are the 3 ways to achieve it. Approach 2 is not allowed at work due to restrictions with using std libraries.
Approach 1:
In C++:
char arr[] = "C++ String";
void * cppstring = arr;
std::cout<<"before:"<<(char*)cppstring<<std::endl; // C++ String
// calling swift function and passing the void buffer to it, so that swift can update the buffer content
Module1::SwiftClass:: ReceiveString (cppstring, length);
std::cout<<"after:"<<(char*)cppstring<<std::endl; // SwiftStr
In Swift:
func ReceiveString (pBuffer : UnsafeMutableRawPointer , pSize : UInt ) -> Void
{
// to convert cpp-str to swift-str:
let swiftStr = String (cString: pBuffer.assumingMemoryBound(to: Int8.self));
print("pBuffer content: \(bufferAsString)");
// to modify cpp-str without converting:
let swiftstr:String = "SwiftStr"
_ = swiftstr.withCString { (cString: UnsafePointer<Int8>) in
pBuffer.initializeMemory(as: Int8.self, from: cString, count: swiftstr.count+1)
}
}
Approach 2:
The ‘String’ type returned from a swift function is received as ‘swift::String’ type in cpp. This is implicitly casted to std::string type. The std::string has the method available to convert it to char *.
void
TWCppClass::StringConversion ()
{
// GetSwiftString() is a swift call that returns swift::String which can be received in std::string type
std::string stdstr = Module1::SwiftClass::GetSwiftString ();
char * cstr = stdstr.data ();
const char * conststr= stdstr.c_str ();
}
Approach 3:
The swift::String type that is obtained from a swift function can be received in char * by directly casting the address of the swift::String. We cannot directly receive a swift::String into a char *.
void
TWCppClass::StringConversion ()
{
// GetSwiftString() is a swift call that returns swift::String
swift::String swiftstr = Module1::SwiftClass::GetSwiftString ();
// obtaining the address of swift string and casting it into char *
char * cstr = (char*)&swiftstr;
}
I have the following method to insert @mentions to a text field:
func insertMention(user: Token, at range: NSRange) -> Void {
let tokenImage: UIImage = renderMentionToken(text: "@\(user.username)")
let attachment: NSTextAttachment = NSTextAttachment()
attachment.image = tokenImage
attachment.bounds = CGRect(x: 0, y: -3, width: tokenImage.size.width, height: tokenImage.size.height)
attachment.accessibilityLabel = user.username
attachment.accessibilityHint = "Mention of \(user.username)"
let attachmentString: NSMutableAttributedString = NSMutableAttributedString(attributedString: NSAttributedString(attachment: attachment))
attachmentString.addAttribute(.TokenID, value: user.id, range: NSRange(location: 0, length: 1))
attachmentString.addAttribute(.Tokenname, value: user.username, range: NSRange(location: 0, length: 1))
let mutableText: NSMutableAttributedString = NSMutableAttributedString(attributedString: textView.attributedText)
mutableText.replaceCharacters(in: range, with: attachmentString)
mutableText.append(NSAttributedString(string: " "))
textView.attributedText = mutableText
textView.selectedRange = NSRange(location: range.location + 2, length: 0)
mentionRange = nil
tableView.isHidden = true
}
When I use XCode's accessibility inspector to inspect the text input, the inserted token is not read by the inspector - instead a whitespace is shown for the token. I want to set the accessibility-label to the string content of the NSTextAttachment. How?
In windows there is a support for generating Xaml strings at runtime for the UI artefact and use it on the main thread for loading the Xaml strings with properties and creating the UI artefact. Below is a code example for it.
static void createxaml(hstring & str) {
str = LR"(
<Button
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
Name="MyButton"
Content="Click Me"
Width="200"
Height="60"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="18"
FontFamily="Segoe UI"
Foreground="White"
)";
}
{
hstring xaml;
createxaml(xaml);
Button obj = XamlReader::Load(xaml).as<Button>();
}
My question is, Is there similar support available in uikit to create ui instances like UIButton. Is there some native support from apple that allows us to create a button object using an XML like string?
I have the following function
private func SetupLocaleObserver ()
{
NotificationCenter.default.addObserver (
forName: NSLocale.currentLocaleDidChangeNotification,
object: nil,
queue: .main
) {_ in
print ("Locale changed to: \(Locale.current.identifier)");
}
}
I call this function inside the viewDidLoad () method of my view controller. The expectation was that whenever I change the system or app-specific language preference, the locale gets changed, and this change triggers my closure which should print "Locale changed to: " on the console.
However, the app gets terminated with a SIGKILL whenever I change the language from the settings. So, it is observed that sometimes my closure runs, while most of the times it does not run - maybe the app dies even before the closure is executed.
So, the question is, what is the use of this particular notification if the corresponding closure isn't guaranteed to be executed before the app dies? Or am I using it the wrong way?
I have a button with the following properties:
accessibilityLabel: "Action Button",
traits: "Button",
accessibilityHint: "Performs the main action".
The voiceover reads the button as follows:
Action Button, Button, Performs the main action.
I want to understand how to configure it to only speak the accessibilityHint or only the accessibilityLabel and never speak the traits.
In another example, a switch has the traits: Button, and Toggle. So these traits are a part of what the voiceover speaks. I want only the accessibilityLabel or accessibilityHint to be spoken in this case.
Please let me know how.
Thanks
In the attached code snippet:
struct ContentView: View {
@State private var vText: String = ""
var body: some View {
TextField("Enter text", text: Binding(
get: { vText },
set: { newValue in
print("Text will change to: \(newValue)")
vText = newValue
}
))
}
}
I have access to the newValue of the text-field whenever the text-field content changes, but how do I detect which key was pressed? I can manually get the diff between previous state and the new value to get the last pressed char but is there a simpler way? Also this approach won't let me detect any modifier keys (such as Alt, Ctrl etc) that the user may have pressed.
Is there a pure swift-ui approach to detect these key presses?
I would like to understand how to programmatically set the position of a cursor in a SwiftUI TextField.
In UIKit this can be done using the selectedTextRange property, but I couldn't find a similar way to achieve this with pure SwiftUI.
I want to figure out something like setCursorPosition (index:) - maybe by tracking the position in a @State or any other way.
I understand that I can do this using UIViewRepresentable but I am looking for a pure SwiftUI solution and wanted to know if there is any.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Button ("Button 1") {
print ("Button 1");
}
.keyboardShortcut("k", modifiers: .command)
Button ("Button 2") {
print ("Button 2");
}
.keyboardShortcut("k", modifiers: .command)
}
}
}
I the above snippet, I have assigned the same keyboard shortcut (cmd +k) to 2 different buttons. According to the docs, if multiple controls are associated with the same shortcut, the first one found is used.
How do I figure out if Button 1 would be found first during the traversal or Button 2 ?
Is it based on the order of declaration? Is it always the case that Button 1 would be found first since it was declared before Button 2 ?