I've added an NSTrackingArea to my NSView because I want a certain rectangular area to show a different cursor. As expected, my view gets a call to it's cursorUpdate:(NSEvent*) method, but how do I tell whether it's an "enter" or "leave".
- (void)cursorUpdate:(NSEvent *)event {
// Do I push or pop my custom NSCursor?
}
I notice the event.modifierFlags changes from 8 to 9. But I don't see any public enum constants to test that, so I don't know if I can depend on that. The public enum contains stuff like this, in the higher bits.
typedef NS_OPTIONS(NSUInteger, NSEventModifierFlags) {
NSEventModifierFlagCapsLock = 1 << 16,
NSEventModifierFlagShift = 1 << 17,
...
The tracking area setup code:
NSRect nsRect = ...
NSTrackingAreaOptions options = NSTrackingCursorUpdate | NSTrackingActiveInKeyWindow;
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect: nsRect options: options owner: owner userInfo: userInfo];
[myView addTrackingArea: trackingArea];
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I created a simple app in Xcode. Installed and ran it in the iOS Simulator. I can also start it from command line like this:
% xcrun simctl launch booted com.example.TestBuildCommands --console
com.example.TestBuildCommands: 52877
%
It just prints that one line and returns my shell prompt. But the help for launch says that --console should: "Block and print the application's stdout and stderr to the current terminal."
In my main() function I have:
int main(int argc, char * argv[]) {
printf("In main.\n");
...
Shouldn't I be seeing that message in my terminal screen?
% xcrun simctl help launch
Launch an application by identifier on a device.
Usage: simctl launch [-w | --wait-for-debugger] [--console|--console-pty] [--stdout=<path>] [--stderr=<path>] [--terminate-running-process] <device> <app bundle identifier> [<argv 1> <argv 2> ... <argv n>]
--console Block and print the application's stdout and stderr to the current terminal.
Signals received by simctl are passed through to the application.
(Cannot be combined with --stdout or --stderr)
[...]
ps. Anyone know how to turn off syntax highlighting in those triple-backquoted code blocks that are meant to be just terminal text, not highlighted code?
When I try to run my app on my iPhone, from Xcode, I get a popup that says Unable to Install "AppName". There is some text in the popup. Here's the first part of it. (I replaced the real app's name with "AppName".)
Anyone know how to fix this?
Unable to install "AppName"
Domain: com.apple.dt.MobileDeviceErrorDomain
Code: -402653103
User Info: {
DVTErrorCreationDateKey = "2024-09-28 04:04:29 +0000";
IDERunOperationFailingWorker = IDEInstalliPhoneLauncher;
}
--
Unable to install "AppName"
Domain: com.apple.dt.MobileDeviceErrorDomain
Code: -402653103
--
Could not inspect the application package.
Domain: com.apple.dt.MobileDeviceErrorDomain
Code: -402653103
User Info: {
DVTRadarComponentKey = 282703;
MobileDeviceErrorCode = "(0xE8000051)";
"com.apple.dtdevicekit.stacktrace" = (
...
This method on UIEvent gets you more touch positions, and I think it's useful for a drawing app, to respond with greater precision to the position of the Pencil stylus.
Is there a similar thing in macOS, for mouse or tablet events? I found this property mouseCoalescingEnabled, but the docs there don't describe how to get the extra events.
I have a View with a DragGesture to resize something, so I tried using onHover to set the macOS cursor to the right resize icon. It doesn't work 100%, because the drag will reset the cursor. Then I have to move the pointer out of the view and back in, to re-trigger the onHover and get the resize cursor again.
swift
private struct HeaderEdgeDragArea: View {
var drag: some Gesture {
DragGesture(minimumDistance: 0, coordinateSpace: .global)
.onChanged { value in
...
}
.onEnded { _ in
...
}
}
var body: some View {
Color.gray.zIndex(2.0).frame(width: 1.0)
.overlay(
Rectangle().frame(width: 8)
.foregroundColor(.clear)
.contentShape(Rectangle())
.border(Color.red, width: 0.5)
.onHover { hovering in
print("hovering: \(hovering)")
if hovering {
NSCursor.resizeLeftRight.push()
} else {
NSCursor.pop()
}
}
.gesture(drag)
)
}
}
I know how to add items to the main menu. But what if I want to connect a handler to one that is already there by default? (For example "Select All").
WindowGroup {
ContentView()
}.commands {
CommandGroup(after: CommandGroupPlacement.pasteboard) {
Button("Select All") { selectAll() }
}
That adds a second "Select All" menu item.
If I use CommandGroup(replacing: ...) then it replaces others, not just the "Select All"
These are properties of Product. Both are type VerificationResult<Transaction>? and they seem very similar. What are some example situations where they would be different?
It would be nice if the documentation discussed this.
Here's the entire app below. On iOS 15, it pops up blank. If you dismiss it and click "Share" again, then it looks right. Is this a bug, or is the code wrong?
struct ContentView: View {
@State private var showShare = false
@State private var shareItems: [Any] = []
var body: some View {
VStack {
Text("Test ActivityViewController")
Button("Share") {
share()
}.sheet(isPresented: $showShare) {
print("dismissed")
} content: {
ActivityViewController(activityItems: shareItems)
}
}
}
func share() {
shareItems = ["test"]
showShare = true
}
}
struct ActivityViewController: UIViewControllerRepresentable {
let activityItems: [Any]
func makeUIViewController(context: Context) -> UIActivityViewController {
let c = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
return c
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
}
I tried to replace UIKit's UIPinchGestureRecognizer with SwiftUI's MagnificationGesture, but it doesn't seem possible in my case. I use the location(in: UIView) function from the former, which allows me to zoom in on that point, specifically. It's a better experience when zooming in on an image.
Can I get that info from the MaginificationGesture? In the example code I see only the CGFloat for the amount of magnification.
This minimal code demonstrates a problem I'm having. As you adjust the Slider (high precision numbers), the TextField sets the model, changing the number's precision to its format.
But I only want it to use the 3-digit fraction for display, or if the user edits in the field. It shouldn't be mutating the model just because it's displaying the value, no?
Is it a bug? It doesn't seem right to me.
struct ContentView: View {
@State var number: Double = 0
// wrap binding to log the `set` calls
var textFieldBinding: Binding<Double> {
Binding { number } set: {
print("Setting from TextField: \($0)")
number = $0
}
}
var sliderBinding: Binding<Double> {
Binding { number } set: {
print("Setting from Slider: \($0)")
number = $0
}
}
var body: some View {
VStack {
TextField("Number", value: textFieldBinding, format: .number.precision(.fractionLength(3)))
Slider(value: sliderBinding, in: 0...5.0)
}.frame(maxWidth: 300)
}
}
When you drag the slider, you see stuff like:
Setting from Slider: 1.0073260217905045
Setting from TextField: 1.007
...
I'm working on a drawing and painting program. When I turn my iPad, I detect the screen change and keep the drawing stable, while allowing the toolbars and things to rotate. But SwiftUI creates a disorienting animation of the main canvas anyway. Is there a way to shut that off?
I'm using the Connect app on my iPad. I'm looking at an app that is barely used, and I see two written reviews. But in the App Store there is only one. Any ideas what could cause this?
The review in question is reporting a possible bug, so I do wonder if this means the user retracted/deleted it.
Hard to believe something this old doesn't work, but it appears so. I set the top to 10 and the bottom to 0, but it uses 10 for both.
Am I doing something wrong, or is it a bug?
sv.edgeInsets = .init(top: 10, left: 10, bottom: 0, right: 0)
Screenshot:
Full code example below.
(This is the ViewController.swift file after creating a new Xcode project with "Interface" of "Storyboard". No other changes to the project template.)
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let sv = NSStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
let v1 = ColoredBlock(.red, width: 20)
let v2 = ColoredBlock(.green, width: 20)
let v3 = ColoredBlock(.blue)
sv.addArrangedSubview(v1)
sv.addArrangedSubview(v2)
sv.addArrangedSubview(v3)
sv.spacing = 0
sv.edgeInsets = .init(top: 10, left: 10, bottom: 0, right: 0)
// sv.setContentHuggingPriority(.required, for: .vertical)
view.addSubview(sv)
pinToFourEdges(view, sv)
}
}
class ColoredBlock: NSView {
let intrinsicHeight: CGFloat
let intrinsicWidth: CGFloat
init(_ color: NSColor, width: CGFloat = NSView.noIntrinsicMetric, height: CGFloat = NSView.noIntrinsicMetric) {
intrinsicWidth = width
intrinsicHeight = height
super.init(frame: .zero)
self.wantsLayer = true
if let layer = self.layer {
layer.backgroundColor = color.cgColor
}
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override var intrinsicContentSize: NSSize {
return NSSize(width: intrinsicWidth, height: intrinsicHeight)
}
}
public func pinToFourEdges(_ view1: NSView, _ view2: NSView) {
view1.topAnchor.constraint(equalTo: view2.topAnchor).isActive = true
view1.bottomAnchor.constraint(equalTo: view2.bottomAnchor).isActive = true
view1.leftAnchor.constraint(equalTo: view2.leftAnchor).isActive = true
view1.rightAnchor.constraint(equalTo: view2.rightAnchor).isActive = true
}
I expected the initializer NLLanguage(rawValue: "...") to return nil if I gave it junk, but it doesn't. It accepts any string. I'm loading values from a database so I'd like to know if I'm getting one that is valid, like "en", "es", etc., as opposed to an error. Is there anyway to check that?
I'm using it to set NLLanguageRecognizer.languageConstraints, so I guess by "valid" I mean all the languages that work with that property.
The struct has a bunch of static constants:
struct NLLanguage {
static let english = ...
static let spanish = ...
...
}
If those all work with NLLanguageRecognizer I guess I can paste them all into a dictionary.
I have an app that plays synthesized speech. If I call the AVSpeechSynthesizer speakUtterance method with a premium voice, then no noise comes out, and the synth never works again. However, if I first use a non-premium voice, it works, and I can then call it with premium voices and they speak too.