Construct and manage a graphical, event-driven user interface for your macOS app using AppKit.

AppKit Documentation

Posts under AppKit tag

244 Posts
Sort by:
Post marked as solved
1 Replies
155 Views
Hi everyone, It is the first time for me working with AppKit and a NSTableView. It is backed by a NSFetchedResultsController for Core Data. When there are changes to the dataset, a Notification is being sent: func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { guard let links = self.fetchedResultsController.fetchedObjects else { return } if self.viewContext.hasChanges { try? self.viewContext.save() } self._links = links NotificationCenter.default.post(name: .reloadLinkList, object: nil) } NotificationCenter.default.publisher(for: .reloadLinkList).receive(on: RunLoop.main).sink { notification in self.list.tableView.reloadData() self.list.linksModel.selectedRows = IndexSet([]) } .store(in: &cancellables) This works great for inserting and updating data. When I try to delete something, I get: Thread 1: Fatal error: UnsafeRawBufferPointer with negative count The code for deleting selected objects looks as following: // selector methode for UIMenuItem`s action @objc func onDeleteSelectedLinks(_ sender: AnyObject) { list.linksModel.deleteLinks(links: selectedLinks) } // Method for deleting links from the view context func deleteLinks(links: [LBLink]) { for link in links { self.viewContext.delete(link) } } Thank you for any help in advance!
Posted
by
Post not yet marked as solved
0 Replies
136 Views
Hi, I am using AVRoutePickerView on macOS via NSViewRepresentable. I am setting the player property with a AVPlayer object. But when I choose via AVRoutePicker one of my HomePods, AVPlayer is ignoring the setting and is still using my Mac as output. Strangely if I left the player property nil and then choosing one of my HomePods via AVRoutePickerView it is working, but only for one AVPlayer, other AVPlayer will be muted. How can I force AVRoutePickerView to use its AVPlayer property? I am testing this with macOS 12.4. Thank you Oleg
Posted
by
omg
Post not yet marked as solved
2 Replies
200 Views
In trying to implement a custom variation of HSplitView/VSplitView for macOS, I found it impossible to achieve correct behavior of the NSCursor while dragging the split view divider. Something else is resetting NSCursor to an arrow cursor when a SwiftUI view updates. Moving the mouse over the divider View changes the NSCursor to a resize cursor. However, when the insertion is blinking, after 1/2 a second, on the blink the cursor changes back to an arrow. Turning off "blink", then hovering over the divider, the NSCursor stays as a resize cursor. However, as soon as you click and drag to move the divider, again it changes back to an arrow cursor, flashing between the two NSCursor as you move the divider. It seems like something in SwiftUI is doing this, but I can't tell. Is it possible to implement a custom VSplitView within SwiftUI and achieve consistent behavior of the NSCursor? Full code below import AppKit import SwiftUI @main struct NSCursorBugApp: App { var body: some Scene { WindowGroup { ContentView() } } } let blinkTimer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect() struct ContentView: View { @State var position = 20.0 @State var opacity = 1.0 @State var blink = true var body: some View { VStack(alignment: .leading, spacing: 0) { Color.gray .frame(height: position - 4) .overlay{ Rectangle().frame(width: 1, height: 20).opacity(opacity).padding(.trailing, 200).padding(20) } PaneDivider(position: $position) Color.cyan Toggle("Blink", isOn: $blink) } .onReceive(blinkTimer) {_ in if blink { opacity = 1 - opacity } } .frame(width: 500, height: 500) .coordinateSpace(name: "stack") } } struct PaneDivider: View { @Binding var position: Double let dividerSize = 8.0 let circleSize = 6.0 var body: some View { Group { Divider() ZStack { Rectangle().fill(Color(white: 0.99)) Circle().frame(width: circleSize, height: circleSize).foregroundColor(Color(white: 0.89)) }.frame(height: 8) Divider() } #if os(macOS) .background(NSCursorView()) #endif .gesture(DragGesture(minimumDistance: 1, coordinateSpace: .named("stack")) .onChanged { position = max(0, $0.location.y) }) } } /// Helper NSView as .background to SwiftUI PaneDivider View to set resize NSCursor when inside view bounds class NSCursorPlatformView : NSView { var horizontal = true var trackingArea: NSTrackingArea? = nil func clearTrackingAreas() { if let trackingArea = trackingArea { removeTrackingArea(trackingArea) } trackingArea = nil } override func updateTrackingAreas() { clearTrackingAreas() let area = NSTrackingArea(rect: bounds, options: [.mouseEnteredAndExited, .mouseMoved, .activeInKeyWindow], owner: self, userInfo: nil) addTrackingArea(area) trackingArea = area } override func viewWillMove(toWindow newWindow: NSWindow?) { if newWindow == nil { clearTrackingAreas() } else { updateTrackingAreas() } } override func mouseEntered(with event: NSEvent) { updateCursor(with: event) } override func mouseExited(with event: NSEvent) { updateCursor(with: event) } override func mouseMoved(with event: NSEvent) { updateCursor(with: event) } override func cursorUpdate(with event: NSEvent) {} // to stop system from resetting cursor after us func updateCursor(with event: NSEvent) { let p = convert(event.locationInWindow, from: nil) if bounds.contains(p) { (horizontal ? NSCursor.resizeUpDown : NSCursor.resizeLeftRight).set() } else { NSCursor.arrow.set() } } } struct NSCursorView: NSViewRepresentable { var horizontal = true func makeNSView(context: Context) -> NSCursorPlatformView { let view = NSCursorPlatformView() view.horizontal = horizontal return view } func updateNSView(_ nsView: NSCursorPlatformView, context: Context) { } }
Posted
by
Post not yet marked as solved
0 Replies
120 Views
I have an older MacOS app where in IB (no storyboards) I created a main window/view and a progress window/view in one xib in response to a menu item. In a new MacOS app (using much of the code from the older menu item code), in IB storyboard I have a window controller/window/view/subviews in the storyboard, but I cannot seem to find a way to also include in the storyboard a progress panel (to hook up to an outlet in the view controller). I can create the same window/panel/progress bar that I had in the older app in a separate xib. So I suppose (in objective c) I can just load the xib??? So, is there a better way to implement a separate progress window(s) in a storyboard and hook them up to outlets? I think I'm missing something And what happened to NSPanels?
Posted
by
Post not yet marked as solved
3 Replies
307 Views
A type of question I see often is "which UI framework is best? SwitUI, UIKit, AppKit, etc?" And the answer is, of course, usually "it depends" or "a mix, depending on what you need". I wanted to re-frame that question with specific parameters. Let's say you were writing Apple Photos for the Mac from the ground up, starting today. For the sake of discussion, it's going to be functionally identical to the Photos app that exists on the Mac today. Which means it: looks and feels like a true, native macOS app should be very performant in terms of rendering and scrolling through a library that may contain hundreds of thousands of photos maintains a large database which can be synced over iCloud etc When you go to write that first line of UI code, which UI framework are you reaching for, and why? If more than one, which ones would you use for each piece, and why? Especially interested to hear any viewpoints from Apple folks in this thought exercise!
Posted
by
Post not yet marked as solved
7 Replies
434 Views
Buenas tardes, I have a problem with a control inside an nsalert from a thread calling it on the main thread. Everything works fine but the textfield does not respond, you write or delete and it has no response. dispatch_sync(dispatch_get_main_queue(), ^{ NSAlert *alert = [[NSAlert alloc] init]; [alert setMessageText:@"Enter PIN"]; [alert addButtonWithTitle:@"OK"]; [alert addButtonWithTitle:@"Cancel"]; NSSecureTextField *input = [[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)]; [input setStringValue:@""]; [alertsetAccessoryView:input]; [inputsetEditable:true]; NSInteger button = [alert runModal]; if (button == NSAlertFirstButtonReturn) { self.pin = [input stringValue]; [self.wait signal]; }else if (button == NSAlertSecondButtonReturn) { [Utils Log:@"Pin canceled!"]; [alert.window close]; [self.wait signal]; } }); If I try to create an NSWindow, it comes out as disabled and the controls can't be used either. Thanks greetings
Posted
by
Post not yet marked as solved
10 Replies
785 Views
I have a persistent "crash" with at least one of my apps, which appears to be a case of the app either quitting or being force-quit without generating a crash log. The app doesn't subscribe to any sudden termination compatibility or similar. I have a good friend who is a developer who is able to reproduce the issue within minutes, so I've captured a trove of information from him including a complete sysdiagnose. Unfortunately nothing is jumping out at me, and the only things that show up that seem like they might be related are keys like ApplicationWouldBeTerminatedByTAL and NSCanQuitQuietlyAndSafelyKey. I am kind of grasping at straws and would welcome any inspiration anybody can share. What is TAL and is it something the system could be imposing on my app? If there are circumstances where macOS will preemptively terminate a running app, what are they, and how can I figure out which one is causing the quits in these situatoins? I'd love to be able to reproduce the behavior on my own Mac. If it's something I can prevent, great, if it's not, it would be good to know how to distinguish it from a regular crash for reporting purposes. Thanks for any help!
Posted
by
Post not yet marked as solved
1 Replies
201 Views
I developed a screen watermarking program that worked fine before macOS 12.4. After upgrading to 12.4, "System Extension Blocked" pop-up cann't be click, but the other window is ok. Any body can tell me the macOS 12.4 has do what to "System Extension Blocked" pop-up !!! my sample code like this code-block NSScreen *screen = [NSScreen screens][0]; CGFloat windowWidth = screen.frame.size.width; CGFloat windowHeight = screen.frame.size.height; CGFloat x = screen.frame.origin.x; CGFloat y = screen.frame.origin.y; MyView* view = [[MyView alloc]initWithFrame:NSMakeRect(0, 0, windowWidth, windowHeight)]; NSWindow* window = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, windowWidth, windowHeight) styleMask: NSWindowStyleMaskBorderless | NSWindowStyleMaskNonactivatingPanel backing:NSBackingStoreBuffered defer:NO]; [window setOpaque:NO]; [window setBackgroundColor:[NSColor clearColor]]; [window setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorFullScreenAuxiliary]; [window setIgnoresMouseEvents:YES]; [window setHasShadow:NO]; [window setLevel:NSScreenSaverWindowLevel]; [window setContentView:views]; [window makeKeyAndOrderFront:nil]; and draw in MyView code-block - (void)drawRect:(NSRect)dirtyRect { NSRect screen = [self bounds]; int SW = screen.size.width; int SH = screen.size.height; [[NSColor clearColor] set]; NSRectFill(screen); NSString * strH= @"watermark test."; NSMutableDictionary *md = [NSMutableDictionary dictionary]; [md setObject:[NSFont fontWithName:@"Times" size:80] forKey:NSFontAttributeName]; [strH drawAtPoint:NSMakePoint(SH*0.5, SH*0.5) withAttributes:md]; [self setNeedsDisplay:YES]; }
Posted
by
Post not yet marked as solved
2 Replies
236 Views
I'm working on an iPad app, which I want to be able to run properly on the M1 Mac. I am not using Mac Catalyst because I am using OpenGL, which is not available for Catalyst. Instead, I am targeting "My Mac(Designed for iPad) when I build for the M1 Mac. I would like to know when my app has been placed in full screen mode (when running on the M1 Mac). MacOS (AppKit?) provides the "NSWindowDidEnterFullScreenNotification" to help with this. In general, I'd love to be able to access these "NSWindow*" notifications from within my iOS app, but specifically, I get the error: "Use of undeclared identifier 'NSWindowDidEnterFullScreenNotification' when I use "[NSNotificationCenter defaultCenter] addObserver" to get notified when my app goes full screen. Any ideas as to how I can bridge this gap between iOS and MacOS and get notifications from MacOS, without resorting to Mac Catalyst? This capability would be extremely useful.
Posted
by
Post marked as solved
4 Replies
369 Views
I have an executable (Google Chrome) that apparently "is running setugid()". I cannot find a way to make it work when called from within a /usr/bin/sandbox-exec sandbox without sudo. Given the following sandbox profile: (version 1) (allow process-exec (literal "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome") (literal "/usr/bin/sudo") (with no-sandbox) ) The following two commands work: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome /usr/bin/sandbox-exec -f ./profile.sb sudo /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome (although the second one is really not smart) but this does not work: $ /usr/bin/sandbox-exec -f ./profile.sb /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome 2022-06-07 23:06:50.267 Google Chrome[21533:679255] The application with bundle ID com.google.Chrome is running setugid(), which is not allowed. Exiting. I'm not sure what's preventing chrome from "running setugid()". I've read somewhere that it's something called "AppKit", but I'm not sure how it gets involved here. Is there a way to have sandbox-exec allow the chrome process to do what it needs, without sudo? Any help is appreciated.
Posted
by
Post not yet marked as solved
1 Replies
156 Views
Hi All, I 'm developing a SwiftUI based Mac app that amongst other things has a text editor. The editor is subclassed from NSTextView and some additional functionality added. It is also wrapped in a NSViewRepresentable to make it a SwiftUI View. I'd like to add a standard Find/Replace functionality to it - menu items, find/replace bar or panel, and etc. I did read the documentation on NSTextFinder and NSTextFinderClient, but it's kind of hard to see the full picture how these classes should be used together. Also, since this is SwiftUI based app, I'm not using story boards. If you know any examples, tutorials, or just code snippets that could help me get start, please share. Amy links are greatly appreciated. Thanks!
Posted
by
Post marked as solved
2 Replies
179 Views
I was experimenting with NSSpellChecker on a macOS app with Swift and I noticed that when there are no spelling mistakes it returns an out of bounds range, specifically one with a lowerBound equals to the max value of a 64-bit signed integer. Am I doing something wrong or is it a bug on Apple's part? let sentence = "What a beautiful world." let range = NSSpellChecker.shared.checkSpelling(of: sentence, startingAt: 0) // "What a beautiful world." range: {9223372036854775807, 0} // "What a beautiful worldk." range: {17, 6}
Posted
by
Post not yet marked as solved
2 Replies
193 Views
I'm evaluating switching an application device from windows10 to macOS but one of the key features needed that I'm unsure of is kiosk mode in macOS. Does something like that exist? The application would need to be the only app running (in full screen) and nothing else should show up. Even keyboard shortcuts should be disabled. Is that configuration possible? Is it something to be done in the app program or does it need UWP kind of stuff? Thanks
Posted
by
CRX
Post not yet marked as solved
0 Replies
118 Views
How could I have both pan gesture recognizing (NSPanGestureRecognizer) and mouse capturing (CGAssociateMouseAndMouseCursorPosition(false)) working together? Is it possible at all?
Posted
by
Post marked as solved
2 Replies
218 Views
This question is mainly just a point of curiosity and education. I'm working on one of my first macOS apps, and I see I can check NSApplication.shared.windows to get a list of all the application's windows. Most of the time, this list contains the windows I've programmed which are in memory. Sometimes, though, it also contains two instances of NSMenuWindowManagerWindow. This doesn't appear to be a documented type, and I'm inferring I'm seeing evidence of something NSApplication or the system is doing to help deliver or render some kind of standard application behaviour. I'm wondering whether any macOS gurus (or engineers) can shine some light on it.
Posted
by
Post not yet marked as solved
0 Replies
133 Views
Background: I'm targeting macOS 11 and up, running macOS 12.4 (21F79), and working with Xcode 13.4 (13F17a). I am building an application to show a list of VMs running under my account on a hosting provider. The VMs have a lot of simple properties like a UUID, a name, a comment field, a power state, and so on. They also have a few properties which are lists of relationships to other things. For example, a single VM can have several disks or several network adapters. The VMs can be organized in folders, so I'm trying to use NSOutlineView bound to a tree controller to show the downloaded data. The problem I have is that when I scroll my outline, it has significant animation hitches. Instruments tells me they are due to expensive commits. I originally built the NSOutlineView programmatically, but I've switched to building it in Interface Builder to get the NSTableCellView reuse behavior without needing to subclass and write my own implementations. I have an NSView subclass for the disk column's views and the network adapter column's views. These views present an objectValue property, which gets modified as expected. They then contain a SwiftUI VStack containing a ForEach which renders a row for each disk/interface. View reuse is working, and the internal SwiftUI view properly observes the field for new or removed disks/interfaces. It also properly observes the disk/interface objects themselves for changes (e.g, renaming). Scrolling still has hitches. The hitches get far worse when I bump the number of columns up to the 20 or so I want to use in the real application. I have built a small example project with an object factory instead of an API connection. The full application has a set of different icons representing different types of disk and network for different performance tiers. For now, I have simplified that to a single icon for each: https://github.com/Zimmie0/TableInOutlineExample My questions: Is there a better way to show a list of items with an image and a string of text per item inside a single NSOutlineView or NSTableView cell? Maybe instead of the SwiftUI stuff in the reusable views, I should be building an NSArrayController, an NSTableView with a single column, and using bindings and value transformers (to get an image from the text field indicating the resource's performance tier)? I'm not sure how to do that, though. I specifically don't want a scroll view and a clip view inside the top-level table cells. The top-level table rows should be tall enough objects are never hidden. I'm not sure how to build an NSTableView in interface builder (to get the NSTableCellView bindings and so on) without the scroll view and clip view around it. Also not sure how to tell the system to show the view from some XIB. Could the problem be related to usesAutomaticRowHeights? I'm aware that hurts performance, but I don't know to what extent. I can determine the row height myself easily enough, but I'm not sure how to tell the outline view that a given row's height needs to change in response to a disk or network adapter being added or removed.
Posted
by
Post marked as solved
1 Replies
232 Views
I've been working on a macOS app using pure SwiftUI, and I've found a strange behavior that I've no idea how to solve. If you have enabled the System Preferences > Dock & Menu Bar > Minimize windows into application icon flag, when you minimize the window it never launches again when clicking the app icon on the dock. This does not happen with an AppKit application. The issue can be seen here (video + 2 sample projects): https://github.com/xmollv/macOSMinimizeIssueOnSwiftUI Literally they're empty apps, just created them using Xcode's assistant (the SwiftUI one has the steps to repro the issue in the UI). The only solution that I found to launch the SwiftUI one is rick clicking the app icon, and then selecting the window, but of course nobody expects that. My question is: is there any way launch a minimized SwiftUI app when clicking the dock icon?
Posted
by
Post not yet marked as solved
1 Replies
188 Views
I hope the table column show the values after I pressed the button. The following is the IBAction Button. - (IBAction)buttonTapped:(id)sender { //Filling the arrays Test_name = [NSArray arrayWithObjects:@"test_item_a",@"b",@"c",@"Current",nil]; Min = [NSArray arrayWithObjects:@"0.5",@"0.7",@"0.8",@"100",nil]; Max = [NSArray arrayWithObjects:@"5",@"5",@"9",@"140",nil]; uint16 index = 0; NSInteger i = 0; //Show_Datagrid this function move the above values to another 3 arrays table_item, //table_min, table_max. And the following code is just to verify the value. [self Show_Datagrid:index]; [self showMeg:@"Button Tapped!2\n"]; [self showMeg:[table_item objectAtIndex:0]]; [self showMeg:@"\n"]; [self showMeg:[table_min objectAtIndex:0]]; [self showMeg:@"\n"]; [self showMeg:Column_test_item.identifier]; //call this function to show the values in tableview. [self tableView:_tableview objectValueForTableColumn:Column_test_item row:i]; } following is the function (Column_test_item.identifier is verified correct.): -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { if ([aTableColumn.identifier isEqualToString:@"no"]) return [table_no objectAtIndex:rowIndex]; if ([aTableColumn.identifier isEqualToString:@"item"]) return [table_item objectAtIndex:rowIndex]; if ([aTableColumn.identifier isEqualToString:@"min"]) return [table_min objectAtIndex:rowIndex]; if ([aTableColumn.identifier isEqualToString:@"max"]) return [table_max objectAtIndex:rowIndex]; if ([aTableColumn.identifier isEqualToString:@"value"]) return [table_value objectAtIndex:rowIndex]; if ([aTableColumn.identifier isEqualToString:@"status"]) return [table_status objectAtIndex:rowIndex]; return [table_no objectAtIndex:rowIndex]; } I thnik I called that function in wrong way. Shouldn't I input NSTableColumn parameter Column_test_item directly? Column_test_item is an IBOutlet I connected to the specfic test item column. And how does this function know which column it want to fill up the value, based on the second parameter I input?
Posted
by
Post not yet marked as solved
9 Replies
671 Views
I have an app that displays photos from a directory that the user chooses (including children directories).  On launch it checks UserDefaults for stored values, if none from previous run, then asks user to open a directory of photos. Then initializes itself and saves the UserDefaults and also a persistent url so that on subsequent run can re-open directory without user intervention.   When first run and asks for directory, runs fine in setting up app state and saving UserDefaults and persistent url, but when gets to contentView the ImageView fails to show anything, but app continues running for about 15 or 20 sec. changing photo via timer, but no image displayed and then the crash @main hread 1: EXC_BREAKPOINT (code=1, subcode=0x1b8072158) and occurs seemingly async from the running code. Crash report attached. Then if re-launch app, it gets the saved UserDefaults, does set up and the runs fine, displaying images! Can even change directories (in the full app, with window commands which are not in this short version of the app. Crash Report
Posted
by
Post not yet marked as solved
0 Replies
139 Views
I want to check the contents of an NSItemProvider to validate a drop action in SwiftUI on macOS. I use the code: let urlProviders = info.itemProviders(for: [.url]) if urlProviders.filter({ $0.canLoadObject(ofClass: NSImage.self) }).some { return true } But I get the compilation error: Instance method 'canLoadObject(ofClass:)' requires that 'NSImage' conform to '_ObjectiveCBridgeable' Is this a bug? The same code works with UIImage when compiling for iOS. Xcode 13.4
Posted
by