Creating a context menu via UIContextMenuConfiguration creates the NSMenu as expected on Mac Catalyst but how do I add separator menu items? https://developer.apple.com/documentation/appkit/nsmenuitem/1514838-separatoritem?language=objc
I'm talking about context menus that are shown via right-click, not the menu bar.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
On app launch I'm trying to specify a reasonable initial value for the window's frame.
Using the recommended API I create a UIWindowSceneGeometryPreferencesMac object and pass it to -requestGeometryUpdateWithPreferences:errorHandler: in -scene:willConnectToSession:options:
This method respects the value passed in as the size but does not seem to respect the requested origin. Initially I'm always placed at origin 0, 0 for the first window which doesn't look particularly good. I think I'd like to be inset on the x-axis a bit, or maybe even position the window in the center of the screen on app launch.
Is there anyway to get more control over the window frame on Mac Catalyst?
Is it possible to share multiple links at once on Mac Catalyst to Messages? When I provide multiple urls via the UIActivityItemSource API Messages just picks 1 of the links.
The Mail activity handles multiple links without a problem but I'd like this to work with Messages too. I know for sure this is possible in native AppKit but can't seem to figure out how to get this to work on Catalyst.
I tried providing the links to UIActivityViewController with a UIActivityItemsConfiguration object instead of using the UIActivityItemSource API but that didn't work either.
Thanks in advance
In the WWDC 2022 video "Bring your iOS App to the Mac" there is sample code which shows the recommended way to set the default window size for a new window. According to the presenter it is considered good practice to do this in -scene:willConnectToSession:options:
CGRect systemFrame = scene.effectiveGeometry.systemFrame;
CGRect newFrame = CGRectMake(systemFrame.origin.x,
systemFrame.origin.y,
defaultWindowSize.width,
defaultWindowSize.height);
UIWindowSceneGeometryPreferencesMac *geometryPrefs = [[UIWindowSceneGeometryPreferencesMac alloc]initWithSystemFrame:newFrame];
[scene requestGeometryUpdateWithPreferences:geometryPrefs errorHandler:^(NSError * _Nonnull error)
{
//Error
}];
So I have a button in my UI that opens a new window that uses this window scene delegate class. I have a laptop and external display connected. Now my app's window is on the external display and when I click the button the opens the new window, the new window opens on the laptop's main display (the display physically attached). This is wrong.
Setting the requestingScene property on UISceneActivationRequestOptions makes no difference, the new window still opens on the wrong display no matter what.
If I comment out the above code that sets the initial window size... the window opens on external display as expected (but now I've lost my window size).
According to the UIActivityViewController documentation for UIActivityViewController's completionWithItemsHandler:
Upon the completion of an activity, or the dismissal of the activity view controller, the view controller’s completion block is executed. You can use this block to execute any final code related to the service.
However when invoking the "Messages" or "Mail" actions in the UIActivityViewController this block is never called. I'm presenting the UIActivityViewController in a popover. Simple to reproduce. Just do this on Mac Catalyst in a table view delegate (sorry for the poor code formatting but it is hard to format code well on these forums).
-(UISwipeActionsConfiguration*)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
UIContextualAction *shareAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
title:@"Share"
handler:^(UIContextualAction *action,
UIView * _Nonnull sourceView,
void (^_Nonnull completionHandler)(BOOL))
{
[self showPopoverWithSourceItem:sourceView completionWithItemsHandler:^(UIActivityType _Nullable activityType,
BOOL completed,
NSArray * _Nullable returnedItems,
NSError * _Nullable activityError) {
//This block isn't called when Messages/Mail activities are selected. Probably other too but that's all I tested.
completionHandler(completed); //Need to call the UIContextualAction's completionHandler here to close up the swipe actions.
}];
}];
shareAction.image = [UIImage systemImageNamed:@"square.and.arrow.up.fill"];
UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[shareAction]];
return config;
}
-(void)showPopoverWithSourceItem:(id<UIPopoverPresentationControllerSourceItem>)sourceItem
completionWithItemsHandler:(UIActivityViewControllerCompletionWithItemsHandler)handler
{
NSURL *shareLink = [NSURL URLWithString:@"https://www.apple.com"];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc]initWithActivityItems:@[shareLink]
applicationActivities:nil];
activityViewController.completionWithItemsHandler = handler;
activityViewController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *presentationController;
presentationController = (UIPopoverPresentationController*)activityViewController.presentationController;
presentationController.sourceItem = sourceItem;
presentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:activityViewController animated:YES completion:nil];
}
Run that and choose "Mail" or "Messages" in the activity view controller. The table view remains swiped after the activity is invoked and the popover is dismissed. Now if you click outside the popover without invoking an activity the popover dismisses and the completionWithItemsHandler is called.
Related but different UIActivityViewController/UIActivity bug I reported here yesterday: https://developer.apple.com/forums/thread/722003
I will file a bug on this and post the number here soon.
Can I please work a full day without running into a system bug in this framework....just one day..please.
I wouldn't be so disgruntled about all this if my obvious bug reports actually got fixed in a reasonable amount of time but I've been a developer long enough to know that I'm lucky if they get fixed for macOS 14, if ever.
Is there a way to programmatically determine the default size of an NSToolbarItem when creating them on Mac Catalyst like so:
UIImage *downArrowImage = [UIImage systemImageNamed:@"arrow.down"];
UIBarButtonItem *goDownUIBarButtonItem = [[UIBarButtonItem alloc]initWithImage:downArrowImage style:UIBarButtonItemStylePlain target:nil action:@selector(navigateDownard:)];
NSToolbarItem *nsToolbarItem = [NSToolbarItem itemWithItemIdentifier:itemIdentifier barButtonItem:goDownUIBarButtonItem];
Why am I asking? I need to create a toggle toolbar item (which requires me to change the toolbar item's image when the toggle is flipped.
I can do this by using NSUIViewToolbarItem and embedding a UIButton. But when you feed an SF Symbol image to UIButton and call sizeToFit on it it doesn't generate a view that matches the size of UIBarButtonItems for all the other NSToolbarItems next to it. I can hard code size constraints in like this to make it size properly:
NSLayoutConstraint *width = [theUIButtonToEmbedInToolbarItem.widthAnchor constraintEqualToConstant:32.0];
NSLayoutConstraint *height = [theUIButtonToEmbedInToolbarItem.heightAnchor constraintEqualToConstant:32.0];
//activate these constraints and embed the UIButton in the NSToolbarItem.
And that's works but I'm guessing the size so the layout could break in a OS update.
I tried just feeding an SF Symbol image to NSToolbarItem's image property directly but then the toolbar item doesn't draw at all (edit: this is only true when using an NSToolbarItem subclass, which I created to change the toolbar item's image itself when the toggle property is flipped)
//Inside my NSToolbarItem subclass.
-(void)setOn:(BOOL)isOn
{
if (_on != on)
{
_on = isOn;
self.image = (isOn) ? self.onImage : self.offImage;
}
}
So when using NSToolbaritem's image property directly setting the image property works fine, this means I have to track the toggle state externally which is possible but definitely not as nice).
Edit: Actually if forgot to modify my toolbar item subclass to subclass NSToolbarItem directly (was subclassing NSUIViewToolbarItem when I was first experimenting with using UIButton).
Using the image property on NSToolbarItem directly works for me. So I'm happy. I still think it'd be useful for clients that need to embed custom views inside a NSToolbarItem to get some kind of size recommendation.
Is there any API in Mac Catalyst that wraps the AppKit functionality we get in NSTitlebarAccessoryViewController?
Is it possible to use Settings.bundle just for Mac Catalyst, and not for the iOS version of the app?
I was wondering if it was possible to use a Settings.bundle just for the Mac Catalyst version of the app? On the iOS version I handle my preferences in app as it is easier to sync with iCloud key value storage, plus doing it in-app has the added convenience of not making the user navigate to the Settings app to manage preferences.
On Mac Catalyst however using a Settings.bundle would be nice because I'd get UI for free and the user doesn't have to navigate to a different app to manage preferences. Also I have a few preferences that only apply to the iOS version of the app, and some that only apply to the Mac version of the app (preferences that don't apply to the platform the app is running on should be excluded from the UI).
So is there a way to specify a Settings.bundle just for Mac Catalyst? If not, is there a way to specify that a particular preference is "Mac Only" in the plist files inside the Settings bundle?
When running into a hard to reproduce crash that only occurs in a production build it would be helpful to get more detailed information about the thrown exception. As far as I can tell, Crash reports don't include the NSException's name, reason, or userInfo. Is there any reason why this isn't included in Crash reports provided to developers?
Someone else asking something similar here: https://stackoverflow.com/questions/73327915/how-do-you-add-diagnostic-information-to-ios-crash-reports
Looks like I'm having a bad morning. I'm on 10.11.6 and Xcode 7.3.1.Xcode keeps crashing. When I re-launch Xcode, it restores the window of my open project and crashes again. I rebooted my machine and was able to start working again for about 5 minutes and now it is doing it again.When relaunching I get:Xcode quit unexpectedly while using the dsc_extractor.bundle plug-in.I sent probably 10-15 crash reports to Apple.
When building context menus in UIKit I often have actions contained in a single method which can be invoked in different ways (from a UIButton, a UIBarButtonItem, etc.)
I'd like to simply make a menu item with a target-action pair but UICommand/KeyCommand only takes a selector. It seems kind of silly to have the system enumerate the responder chain in cases where I know who the target is supposed to be and there can and should only be one target (also could unintentionally create bugs when a responder implementing the same method gets the call instead of the target you want).
In AppKit you an easily do this with NSMenuItem. Could be a nice enhancement in UIKit. I know I can wrap the target in UIAction and call the selector in the action handler block but the code is kind of ugly and I'm not sure if there are edge cases where __weak __strong dance is required (in which case the code is even more long winded and ugly. I know swipe actions can occasionally create a retain cycle if you don't do __weak _ __strong dance).
Unless there is a UIMenuElement subclass that provides this and I'm just not aware of it?
Is there any UIKit API that bridges to NSBox in the Mac idiom?
Is there any way to create radio buttons on Mac Catalyst in the Mac idiom (without writing my own from scratch obviously)?
Creating a Settings bundle with PSRadioGroupSpecifier creates a radio button group in the Preference pane but I don't see a way to do this in my own UI?
Is there a way to get native AppKit radio buttons on Mac Catalyst?
The newer documentation about creating a Settings.bundle on Mac Catalyst simply links out to the Documentation Archive:
https://developer.apple.com/library/archive/documentation/PreferenceSettings/Conceptual/SettingsApplicationSchemaReference/Articles/PSGroupSpecifier.html#//apple_ref/doc/uid/TP40007009-SW1
The SupportedUserInterfaceIdioms key is documented:
Indicates that the element is displayed only on specific types of devices. The value of this key is an array of strings with the supported idioms. Include the string “Phone” to display the element on iPhone and iPod touch. Include the string to “Pad” to display it on iPad.
This key is available in iOS 4.2 and later.
Is "Mac" a supported entry to specify a preference for the Mac idiom? It seems to work but I don't see any documentation for this.
It is normal to have a preference like: “Always use Dark Mode” in an app to allow the user to opt in to Dark mode in the current app without turning it on System wide.
On iOS you can manage this by detecting the change in the app preference and when it is turned on you set the overrideUserInterfaceStyle property on the UIWindow to UIUserInterfaceStyleDark. On Mac Catalyst however this does not work. If you set the overrideUserInterfaceStyle property to UIUserInterfaceStyleDark the NSWindow underneath doesn’t update to reflect dark mode. The titlebar doesn’t update for dark mode either. And neither does the NSToolbar. Only UIViewControllers inside the UIWindow reflect the overrideUserInterfaceStyle
Ideally it would be great if there was a overrideUserInterfaceStyle property on UIApplication but there is not. Is there a way to force the NSWindow/NSToolbar created by Mac Catalyst to use a particular appearance (without an Appkit bundle)?