Hi,
I'm using NSPanel that his level is .popUpMenu and when I use .quickLookPreview in SwiftUI it make the the Quick Look behind the nspanel how can I fix it without change the level of NSPanel?
AppKit
RSS for tagConstruct and manage a graphical, event-driven user interface for your macOS app using AppKit.
Post
Replies
Boosts
Views
Activity
I need to bring an iOS application to macOS using Catalyst. This application contain parts where it waits for a button to be pressed in the main thread, using
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
in a while loop to allow some dispatching while waiting. I know that this is not good style, but I need to convert this old source code and mentioned that when using this part of code under Catalyst, the main thread will not dispatch. So the button cannot be clicked, and a beach ball appears after two seconds.
I saw a similar construct for native macOS applications:
NSEvent *event= [[NSApplication sharedApplication] nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate dateWithTimeIntervalSinceNow:0.1] inMode:NSDefaultRunLoopMode dequeue:YES];
if (event) {
[[NSApplication sharedApplication] sendEvent:event]; }
but I do not have access to NSEvent and NSApplication in a Catalyst environment.
Question: I there any code snippet which I can use to achieve the above? I do not want to completely rewrite old code if there is a solution for this. Any ideas or hints are highly appreciated.
Thank you!
Markus
I need to create multiple share extensions for a single mac application, but all the share extensions are displaying the app's icon. Is it possible to customize different icons for each share extension?
I understand the mvc thing kinda, theres an array as a model, a tableview as a control, and the interface as a control (right?)
so like, I drag an array controller on to the form display thing, assign a delegate to it the view and app module/header, add data to it and the tableview updates after I add a function to it? in vs the events are in the event browser, do I just copy and paste the code from the tutorial?
how do I add controls and do all the advanced stuff? the documentation on developer.apple.com isnt that detailed, and most books are outdated or n/a since its objective c
tutorials would be nice, some home grown method would be cool too
thank you
unidef warrell yashizzo
For a Cocoa project I have this table view controller:
@interface TableViewController : NSObject <NSTableViewDataSource, NSTableViewDelegate>
@property (nonatomic, strong) NSMutableArray *numbers;
@property (nonatomic, strong) NSMutableArray *letters;
@end
#import "TableViewController.h"
@implementation TableViewController
- (NSMutableArray *)numbers
{
if (!_numbers)
{
_numbers = [NSMutableArray arrayWithArray:@[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10"]];
}
return _numbers;
}
- (NSMutableArray *)letters
{
if (!_letters)
{
_letters = [NSMutableArray arrayWithArray: @[@"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j"]];
}
return _letters;
}
// NSTableViewDataSource Protocol Method
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
return self.numbers.count;
}
// NSTableViewDelegate Protocol Method
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSString *identifier = tableColumn.identifier;
NSTableCellView *cell = [tableView makeViewWithIdentifier:identifier owner:self];
if ([identifier isEqualToString:@"numbers"])
{
cell.textField.stringValue = [self.numbers objectAtIndex:row];
}
else
{
cell.textField.stringValue = [self.letters objectAtIndex:row];
}
return cell;
}
In the storyboard I created a NSTableView and set up the connection, after running it I get what I expected:
okay, cool, but I have a question:
why is this working even though I haven't created a NSTableView as a property for my ViewController or for my TableViewController?
Also, there's another problem, now I want to add a button to this window such that, every time I click it, a new item should be added to this table(for now it can be anything)
So I created a button and a method for this and linked the action to the story board:
-(IBAction) addNewNumber:(id)sender
{
[_numbers addObject:@"1234"];
[_letters addObject:@"testing"];
}
Now, every time I click this button I can see that this method is indeed being called and that indeed IT IS adding a new member to these arrays, the thing is, the table is not being updated, what gives? Any advice on how I can fix this behavior?
I have created a progress indicator to simulate some progressing download task in the dock icon. However, I can see the progress bar appearing in the dock icon but it is not getting updated when I invoked the updateProgress() method. Ideally it should have updated it, and I m not able to figure out the reason?
I have creating the same NSProgressIndicator on an NSWindow and it works to update the progress bar with the same code. Anything that I m missing to understand here? Below is the code I m using:
class AppDelegate: NSObject, NSApplicationDelegate {
var progressIndicator: NSProgressIndicator!
let dockTile = NSApp.dockTile
func applicationWillFinishLaunching(_ notification: Notification) {
// Step 1: Create a progress bar (NSProgressIndicator)
progressIndicator = NSProgressIndicator(frame: NSRect(x: 10, y: 10, width: 100, height: 20))
progressIndicator.isIndeterminate = false
progressIndicator.minValue = 0.0
progressIndicator.maxValue = 100.0
progressIndicator.doubleValue = 0.0
progressIndicator.style = .bar
dockTile.contentView = progressIndicator
dockTile.display()
//// Update the progress bar for demonstration
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.updateProgress(50)
}
}
func updateProgress(_ value: Double) {
progressIndicator.doubleValue = value
NSApp.dockTile.display()
}
}
I need to add an accessory view with a text field to an NSAlert. This works as expected but as my app comes in different languages, the alert looks a bit different depending on the language used:
So I wonder how I can make the text field automatically use the full width of the alert window. I tried to call the alert's layout method and then resize the text field but this seems not work in all cases. Any help would be highly appreciated. Thanks!
I want to make a simple droplet application. I've set the document types to include com.adobe.pdf files, and I am now receiving callbacks to the app delegate's application(_:open:) callback when I drop PDFs on the app icon…
But not the first time. It doesn't matter how long I wait, or whether the app is already open—the first drop never triggers the callback. All subequent drops work as expected, and I get URLs to all the files dropped.
What might be wrong? How can I debug this?
I have a Cocoa application and I'm trying to set up an NSImageView without using story board (using storyboard works just fine tho).
Also, I'm kinda new to Cocoa so any advice is appreciated.
Anyway so here's the deal, I created a class to encapsulate this image:
@interface MyView : NSView
{
@private
NSImageView* imageView;
}
@end
@implementation MyView
-(id) initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if(self)
{
NSRect rect = NSMakeRect(10, 10, 100, 200);
imageView = [[NSImageView alloc] initWithFrame:rect];
NSImage* image = [NSImage imageNamed:@"bob.jpeg"];
[imageView setImageScaling:NSImageScaleNone];
[imageView setImage: image];
[self addSubview: imageView];
}
return self;
}
-(id) init
{
return [self initWithFrame:NSMakeRect(10, 10, 100, 100)];
}
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
// Drawing code here.
}
@end
Now, in the view controller file, in the viewDidLoad I tried to load add this as a subview to get it to display my image:
- (void)viewDidLoad
{
[super viewDidLoad];
MyView *customView = [[MyView alloc] init];
[self.view addSubview:customView];
}
This kinda works, except that it loads the image twice, I ended up with two images instead of just one like I intended, what gives? what am I doing wrong here?
Hi, in my macOS app I am modifying the mouse cursor image for some user interactions. I also have an NSSlider in the app which can be changed programmatically by setting its doubleValue. I've noticed that whenever the slider is set programmatically the custom mouse cursor is lost and changes back to an arrow. This doesn't happen if other controls are changed programmatically, e.g. the progress bar. Any ideas on how I can prevent this happening?
I have an object that is an NSRuleEditorDelegate for an NSRuleEditor whose nestingMode is NSRuleEditorNestingModeList. There are 8 different possible criteria. Each criterion is optional but at least 1 is required (ruleEditor.canRemoveAllRows = NO). Each criterion should only be added once. How can I limit adding a criterion for a row if it is already in the editor at a different row?
Thanks!
I am using NSMenuToolbarItem to show a drop-down menu in my NSToolbar. This works as expected when creating an NSMenu beforehand and assign it to the menu property of NSMenuToolbarItem.
However, my menu needs to be built dynamically when the user clicks the dropdown button. To do that, I am using NSMenuDelegate. When creating the menu in the menuNeedsUpdate of the delegate, the first menu item isn't shown to the user. Why?
Menu when using delegate:
Menu when pre-assigning menu:
I also cannot just add a placeholder menu item at the start of the NSMenuToolbarItem as all menu items do show in the overflow menu.
Example code:
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate, NSToolbarDelegate, NSMenuDelegate {
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 400, height: 300),
styleMask: [.titled, .closable, .resizable],
backing: .buffered,
defer: false)
window.makeKeyAndOrderFront(nil)
let toolbar = NSToolbar(identifier: "MainToolbar")
toolbar.delegate = self
window.toolbar = toolbar
}
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [NSToolbarItem.Identifier("item1"), NSToolbarItem.Identifier("item2")]
}
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [NSToolbarItem.Identifier("item1"), NSToolbarItem.Identifier("item2")]
}
func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier,
willBeInsertedIntoToolbar: Bool) -> NSToolbarItem? {
let item = NSMenuToolbarItem(itemIdentifier: itemIdentifier)
if itemIdentifier == NSToolbarItem.Identifier("item1") {
let menu = NSMenu()
fillMenuWithItems(menu)
item.menu = menu
} else if itemIdentifier == NSToolbarItem.Identifier("item2") {
item.menu = NSMenu()
item.menu.delegate = self
}
return item
}
func menuNeedsUpdate(_ menu: NSMenu) {
menu.removeAllItems()
fillMenuWithItems(menu)
}
func fillMenuWithItems(_ menu: NSMenu) {
menu.addItem(NSMenuItem(title: "Option 1", action: nil, keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "Option 2", action: nil, keyEquivalent: ""))
}
}
I have a NSWindow subclass. The window has a custom shape, and thus has a custom contentView which overrides drawRect to draw .
Since the window has a custom shape it cannot use the system provided titlebar.
The problem I'm having is when there are multiple screens, if my window is on the inactive screen (not mainScreen with menu bar) and I move the mouse over to the second monitor and click the window....the menu bar doesn't travel to the screen my app is on after the window is clicked.
This does not happen with any other window. In all other windows, the menu bar moves to the screen once you click a window on that screen. So it appears this is because my window is not using NSWindowStyleMaskTitled. As far as I know, I can't use the system title bar and draw my custom window shape. Abandoning the custom window shape is not an option.
Without going into too many details as to why I care, the menu bar really should travel with first click on my window like other apps.. Is there a way to tell the system (other than using the NSWindowStyleMaskTitled) that clicking on my window should make that screen the "main screen" (bring the menu bar over?
I tried programmatically activating the application, ordering the window to the front, etc. but none of this works. This forces the user to click outside my app window, say on the desktop, to move the menu bar over, which feels wrong.
Thanks in advance if anyone has any suggestions.
After each macOS update come new annoying log messages.
So after updating to Sonoma and Xcode 16, I see the following logged in the Xcode console whenever my app shows an NSPredicateEditor.
Failed to find localization for values: All, of the following are true
I tried setting the "localize" attribute to "never" in the attributes inspector of the corresponding menu/text fields from interface builder, to no avail.
Any suggestions ?
In Monterey, when a user was at the top of a ScrollView implemented inside of a NSHostingController's view (that was itself embedded in a window with a NSToolbar), the window's toolbar background would be hidden until the user scrolled from the top.
In Ventura, this behavior is different, with the toolbar's background visible all of the time unless a traditional NSScrollView is used (which means no SwiftUI).
Is there the ability to change this behavior within SwiftUI some how now?
In the WWDC22 talk "What's new in TextKit and text views" (https://developer.apple.com/videos/play/wwdc2022/10090?time=408), it was announced (at minute 6:45) that TextKit 2 & NSTextList is supposed to be working on both UIKit and AppKit.
While NSTextLists are correctly rendering on iOS, they are not working on macOS. The paragraphs aren't inset and the numbers/bullets do not render in front of the list items.
Any help?
let textView = NSTextView(frame: self.view.bounds)
textView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(textView)
let safeArea = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
textView.topAnchor.constraint(equalTo: safeArea.topAnchor),
textView.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor),
textView.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor),
textView.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor)
])
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.textLists = [NSTextList(markerFormat: NSTextList.MarkerFormat("{decimal}."), options: 0)]
let attributedText = NSMutableAttributedString("Item 1\nItem 2\nItem 3\nItem 4f")
attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.length))
textView.textStorage?.setAttributedString(attributedText)
When using the new ‘addSymbolEffect’ effect method on NSImageView with the ‘.rotate.byLayer’ parameter with an applicable SF Symbol 6 symbol, the resulting animation is not completely as expected, to say it mildly.
This is the code line I use:
imageView.addSymbolEffect(.rotate.byLayer, options: .repeat(.continuous), animated: true)
The correct layer rotates around the correct anchor point, but the whole image is moving up and down.
The same code with the same symbol in iOS 18 beta runs perfectly.
Does anyone know how to get this new rotate API correctly working in macOS 15 beta?
In case an Apple engineer reads this:
FB13916874 contains example projects for macOS (wobbling rotation) and iOS (perfect rotation), and a screen recording what I see in macOS 15 beta.
Bit of a stream of consciousness below. I discovered after writing all that that I needed to switch width & height when setting values, and print landscape. That gets things to print as expected. But I really need to be able to set the Brother's notion of tape width in the Basic Options portion of the print panel.
I've got this Brother QL-800 USB label printer that takes spools of either die-cut labels, or continuous paper of a given width. It can cut between labels or the continuous paper at any point.
My app is intended to print small labels for small parts drawers. The app has a DB of parts, and I want to print dozens of unique labels of a specific height and width. Ideally, you'd set things up once, and then print one or more specific part labels without further UI interaction.
The NSPrintPanel is far too complex, and allows the user to ***** things up, so I'd like to forego it altogether.
I've written some simple code that does succeed in printing via the NSPrintPanel, but it’s positioning the text ultimately incorrectly.
I can't figure out how to properly size a view to print a label. I can get an NSPrintInfo object that knows the label printer is selected (e.g. it shows the right name for NSPrintInfo.printer.name). But it states the paperSize is (612.0, 792.0), which if I assume 72 ppi, comes out to 8.5" x 11", which this paper clearly is not.
func
printLabel()
{
Task
{
let printInfo = NSPrintInfo()
let printer = printInfo.printer
print("Paper size: \(printInfo.paperSize)")
// printInfo.paperSize = CGSize(width: 47 / 25.4 * 72.0, height: 12.0 / 25.4 * 72.0)
printInfo.topMargin = 0.0
printInfo.bottomMargin = 0.0
printInfo.leftMargin = 0.0
printInfo.rightMargin = 0.0
printInfo.orientation = .landscape
printInfo.isHorizontallyCentered = false
printInfo.isVerticallyCentered = false
printInfo.scalingFactor = 1.0
let view = NSHostingView(rootView: createLabelPrintView())
view.frame.size = CGSize(width: 25 / 25.4 * 72.0, height: 12.0 / 25.4 * 72.0)
let op = NSPrintOperation(view: view, printInfo: printInfo)
op.showsPrintPanel = true
op.showsProgressPanel = true
op.printPanel.options.insert(.showsPaperSize)
op.printPanel.options.insert(.showsOrientation)
op.run()
}
}
@ViewBuilder
func
createLabelPrintView()
-> some View
{
VStack(spacing: 0)
{
Text("Line 1")
Text("Line 2")
}
.padding(0)
}
If I set the pageSize explicitly (uncommenting the line above),
The printer offers a long list of available sizes (although none I've found corresponds to the 0.47"/12 mm x continuous spool). By the way, it never remembers the size I selected, and always reverts to 8.5 x 11, which it will then refuse to print, hanging in Print Center with an error about mismatched page sizes.
I don’t know why the available page sizes have multiple sizes that don’t seem to match. E.g. 0.47"
In the printer’s “Basic Options,” it shows the notion of a Width that's "not found," if I use a custom size:
I don't really understand where those printer options can be found and set.
Hmm, maybe I found a clue: I ran an NSPrintPanel by itself and examined the NSPrintInfo afterward:
let panel = NSPrintPanel()
panel.options.insert(.showsPaperSize)
panel.options.insert(.showsOrientation)
let result = await panel.beginSheet(using: printInfo, on: NSApplication.shared.windows.first!)
print("Result: \(result)")
print("Paper size: \(printInfo.paperSize)")
print("Settings: \(printInfo.printSettings)")
Paper size: (283.44000244140625, 82.08000183105469)
Settings: {
"AP_D_InputSlot" = "";
BrAutoTapeCut = ON;
BrBiDiPrint = ON;
BrBrightness = 0;
BrContrast = 0;
BrCutAtEnd = ON;
BrCutLabel = 1;
BrHalftonePattern = BrErrorDiffusion;
BrMargin = "3.0";
BrMultiColor = BrMultiColorMonochrome;
BrRedLevel = 0;
BrRemoveBlkSpace = OFF;
BrResolution = BrSpeed300x300dpi;
BrTapeLength = "69.1";
ColorModel = Gray;
Duplex = None;
PaperInfoIsSuggested = 0;
Resolution = 300x300dpi;
"com_apple_print_DialogDismissedBy" = Print;
"com_apple_print_DocumentTicket_PMSpoolFormat" = "application/pdf";
"com_apple_print_PDEsUsed" = "Printer Options";
"com_apple_print_PageToPaperMappingMediaName" = 29mm;
"com_apple_print_PageToPaperMappingType" = 1;
"com_apple_print_PrintSettings_PMCopies" = 1;
"com_apple_print_PrintSettings_PMCopyCollate" = 1;
"com_apple_print_PrintSettings_PMDestinationType" = 1;
"com_apple_print_PrintSettings_PMDuplexing" = 1;
"com_apple_print_PrintSettings_PMFirstPage" = 1;
"com_apple_print_PrintSettings_PMLastPage" = 2147483647;
"com_apple_print_PrintSettings_PMPageRange" = (
1,
2147483647
);
"com_apple_print_ticket_type" = "com.apple.print.PrintSettingsTicket";
"com_apple_print_totalPages" = 2147483647;
}
It has added a bunch of Br-prefixed keys that clearly correspond to some of the options in the UI. But I'm not sure if I can set those programmatically and get things to print the way I expect. And I don't see anything for tape width.
How do I get an NSPrintPanel to show the preview without an NSPrintOperation? I want to react to any changes the user might make before things go to print.
I have a simple cocoa project, it has the default files like AppDelegate.m, AppDelegate.h , ViewController.h and ViewController.m what I want is to set the Window title to the dimension of the current window and update it as the user resizes it.
My Storyboard has an Application Scene, a Window Controller Scene and a test Scene which contains my view:
how do I go about this? should my ViewController or AppController implement NSWindowDelegate ?
We have a xib file that contains a toolbar with some items in it. The toolbar has an IBOutlet defined in its files owner. Before macOS 15 - we were able to reach the items in the toolbar by using the items property.
The File Owner for the xib containing the toolbar is a NSViewController
e.g.
@IBOutlet var theToolbar: NSToolbar!
required init?(coder: NSCoder) {
super.init(coder: coder)
Bundle.main.loadNibNamed("ToolbarDesign", owner: self, topLevelObjects:nil)
}
and then later in code...
func getItems()
{
let items:[NSToolbarItem]? = mainRightToolbar?.items
}
Prior to macOS15 - items would contain the NSToolbarItems specified in the xib design. Now, in macOS 15 - the items array is not nil but doesn't contain any items either.
What needs to be don't for macOS15 specifically to enable the items property of NSToolbar to work again?