For those with existing projects that rely on a SceneDelegate and are primarily UIKit-based, I am curious how one might launch a window with a style of volumetric or an ImmersiveSpace. Is this possible without having a SwiftUI-based @Main entry point?
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Post
Replies
Boosts
Views
Activity
On iOS17, UIDevice.current.batteryLevel is returning values rounded to 0.05, such as 1, 0.95, 0.9. Which used to be a 1% granularity in iOS16. Is this a bug or a new feature?
I've tried to animate custom UIViewRepresentable with SwitfUI animations, but it doesn't work. It just sets value without interpolation. What should i do to use interpolation values in UIKit views?
My example shows two "progress bars" red one is UIKit view, blue one is SwiftUI version. Sliders controls value directly, randomize button changes value to random with 5s animation.
When I press button SwiftUI progress bar animates exactly as it should, but UIKit's one just jumps to final position.
Set block of animatableData inside Animatable extension not called.
How can I use SwiftUI animation value interpolations for UIKit?
import SwiftUI
import UIKit
class UIAnimationView: UIView {
var progress: CGFloat = 0.5 {
didSet {
if self.progressConstraint != nil, self.innerView != nil {
self.removeConstraint(self.progressConstraint!)
}
let progressConstraint = NSLayoutConstraint(
item: innerView!,
attribute: .trailing,
relatedBy: .equal,
toItem: self,
attribute: .trailing,
multiplier: min(1.0, max(0.0001, progress)),
constant: 0
)
self.addConstraint(progressConstraint)
self.progressConstraint = progressConstraint
self.layoutIfNeeded()
}
}
var innerView: UIView?
private var progressConstraint: NSLayoutConstraint?
public override init(frame: CGRect) {
super.init(frame: frame)
self.performInit()
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
self.performInit()
}
private func performInit() {
let innerView = UIView()
innerView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(innerView)
self.leadingAnchor.constraint(equalTo: innerView.leadingAnchor).isActive = true
self.topAnchor.constraint(equalTo: innerView.topAnchor).isActive = true
self.bottomAnchor.constraint(equalTo: innerView.bottomAnchor).isActive = true
let progressConstraint = NSLayoutConstraint(
item: innerView,
attribute: .trailing,
relatedBy: .equal,
toItem: self,
attribute: .trailing,
multiplier: progress,
constant: 0
)
self.progressConstraint = progressConstraint
self.addConstraint(progressConstraint)
self.innerView = innerView
self.innerView!.backgroundColor = UIColor.red
self.backgroundColor = UIColor.black
}
}
struct AnimationTest: UIViewRepresentable {
var progress: CGFloat
typealias UIViewType = UIAnimationView
func updateUIView(_ uiView: UIAnimationView, context: Context) {
print("progress: \(progress) \(context.transaction.isContinuous)")
uiView.progress = progress
}
func makeUIView(context: Context) -> UIAnimationView {
let view = UIAnimationView()
view.progress = progress
return view
}
}
extension AnimationTest: Animatable {
var animatableData: CGFloat {
get {
return progress
}
set {
print("Animation \(newValue)")
progress = newValue
}
}
}
struct AnimationDebug: View {
@State var progress: CGFloat = 0.75
var body: some View {
VStack {
AnimationTest(progress: progress)
Spacer()
VStack {
Slider(value: $progress, in: 0...1) {
Text("Progress")
}
}
GeometryReader { gr in
Color.blue
.frame(
width: gr.size.width * progress,
height: 48)
}
.frame(height: 48)
Button("Randomize") {
withAnimation(Animation.easeInOut(duration: 5)) {
progress = CGFloat.random(in: 0...1)
}
}
}
}
}
struct AnimationTest_Previews: PreviewProvider {
static var previews: some View {
AnimationDebug()
}
}
Follow up to this thread, does adjustsFontSizeToFitWidth also follow the same thinking? Is it assumed that if we use a font style, this doesn't need to be set in a UIButton if we're using UIButtonConfiguration?
Hello!
I've tested/implemented TipKit in SwiftUI and UIKit but it seems that the close, i.e. X, button doesn't work in UIKit but does in SwiftUI. Not sure if this is a bug or I have to do something different about it in UIKit.
Testing with Xcode 15 Beta 8
Thanks!
According to UIRequiredDeviceCapabilities documentation https://developer.apple.com/documentation/bundleresources/information_property_list/uirequireddevicecapabilities/, the value iphone-performance-gaming-tier has been added. The description is quoted below.
iphone-performance-gaming-tier
Requires the graphics performance and gaming features equivalent to the iPhone 15 Pro and iPhone 15 Pro Max. Available in iOS 17.0 and later. Unavailable in visionOS.
In Info.plist of Xcode 15.0 (15A240d), setting iphone-performance-gaming-tier is correctly displayed in human readable format.
However, when archiving a build containing this value and submitting it to App Store Connect, I receive an email stating that the bundle is invalid.
The iphone-performance-gaming-tier is not available at this time, although its documentation states that it is available in iOS 17.0 and later. How can I use this value? For example, do I need a special entitlement?
Hello! I've been digging into this for a little bit now, and am hitting something of a wall. Our app is crashing occasionally, and googling the crash yields literally 0 results.
Tl;dr: Something related to adaptivePresentationStyle(for:traitCollection:) is resulting in our app crashing.
Context
In our app, we have a custom UIPresentationController that we use to present a small sheet of content overlaying other app content - similar to a UISheetPresentationController with a medium-ish size. So we have a custom UIViewController to present, and it conforms to the UIAdaptivePresentationControllerDelegate protocol. We also have custom present and dismiss animators.
The crash
However, we seem to be running into a really odd crash. I've attached a crash report as well, but here's what one sees in xcode on reproducing the crash:
The _computeToEndFrameForCurrentTransition block is nil inside the _transitionViewForCurrentTransition block, value of outerStrongSelf currently : <XxxYyyyyyZzz.PopupPresentationController: 0x12d017a40>. This most likely indicates that an adaptation is happening after a transtion cleared out _computeToEndFrameForCurrentTransition. Captured debug information outside block: presentationController : <XxxYyyyyyZzz.PopupPresentationController: 0x12d017a40> presentedViewController : <XxxYyyyyyZzz.SomeViewController: 0x12d03a690> presentingViewController : <UINavigationController: 0x12a817400>
2023-09-25_08-02-33.6523_-0500-7d355cd4a86427213389765ef070a777c4b4aaa3.crash
Whenever we present one of these view controllers, things work just fine. When we try to present another one though, if someone is aggressively changing the phone orientation, the app crashes. This crash occurs somewhere in between dismissing the old VC and presenting the new one. It occurs before I ever hit any breakpoints in the "present" animator for the second view controller.
I've narrowed things down a bit, and by commenting out our implementation of adaptivePresentationStyle(for:traitCollection:), the crash can't be reproduced anymore. The downside there being that the app no longer functions how we want it to. Our definition of that function (which causes crashes) looks like this:
public func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
guard forceUsingFullScreenIfCompact else {
return .none
}
return traitCollection.verticalSizeClass == .compact ? .overFullScreen : .none
}
A bit more testing, and it seems like if that function returns the same thing consistently, nothing crashes. Are we not allowed to put conditional logic in this function?
In the crash, we can see that it occurs due to a failing assertion internal to UIPresentationController:
Last Exception Backtrace:
0 CoreFoundation 0x1afa28cb4 __exceptionPreprocess + 164 (NSException.m:202)
1 libobjc.A.dylib 0x1a8abc3d0 objc_exception_throw + 60 (objc-exception.mm:356)
2 Foundation 0x1aa1b2688 -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 172 (NSException.m:251)
3 UIKitCore 0x1b1d05610 __80-[UIPresentationController _initViewHierarchyForPresentationSuperview:inWindow:]_block_invoke + 2588 (UIPresentationController.m:1594)
4 UIKitCore 0x1b21f1ff4 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_3 + 300 (UIPresentationController.m:1228)
The question
This all leads us to wonder if we're doing something wrong, or if there could be a bug in one of the iOS APIs that we're consuming. Thus, posting here. Does anyone have any insight into how this could be occurring, or has seen this before and has ideas? Thanks!
Miscellaneous info
We target iOS 14+
We've seen this issue in debug and release builds from Xcode 14 and 15
We see the issue on users with iOS 15+, though it could be occurring on 14 in just incredibly low numbers
Okay so I'm getting this log every time I present a UIAlertController:
Mac Catalyst: Presenting view controller <UIAlertController: 0x10f027000> from detached view controller <MyViewController: 0x10d104080> is not supported, and may result in incorrect safe area insets and a corrupt root presentation. Make sure <MyViewController: 0x10d104080> is in the view controller hierarchy before presenting from it. Will become a hard exception in a future release.
A few points:
MyViewController is not detached and the presentation shows just fine.
I specifically check for this before presenting the alert controller like so:
BOOL okayToPresentError = (self.isViewLoaded
&& self.view.window != nil);
if (okayToPresentError)
{
[self presentErrorInAlertController:error];
}
else
{
//Wait until view did appear.
self.errorToPresentInViewDidAppear = error;
}
It spews out every time an error is fed back to my app and I present the alert controller (I can turn off the network connection and I show an alert controller with a "retry" button in it which will loop the error back so I can replay the error alert presentation over and over again) .
Every time the alert controller is presented, I get this spewing in the console. Please don't start throwing hard exceptions because the check is faulty.
I have some visualisation-heavy AUv3's, and the goal is not to perform graphics-intensive tasks if the plugin window is not opened inside the host app (such as Logic Pro).
On iOS, this is easily accomplished by the viewWillAppear, etc overrides. But on macOS, it seems these overrides are not called every time the user opens / closes the plugin windows in the host application.
I did try some alternate methods, like trying to traverse the view / controller hierarchy, or make use of the window property, to no avail.
What substitute mechanism could I use to determine visibility status of an AUv3 on macOS?
Thanks in advance,
Zoltan
Hi, I adopted in my app the new default style for the status bar where it switches between light and dark themes depending on the color of the content beneath. It works great until I hide the status bar and show it again. From that point onwards, the status bar will be stuck on the dark or light theme, depending on the app's theme.
This happens as well if the status bar is initially hidden on startup. In that case, the default behavior never works.
I filed an issue (FB13222217), and as of now I didn't find a workaround except never hiding the status bar on my app. I attached a super minimalist example project there, just a scroll view with black and white views and nothing more.
This happens on SwiftUI and UIKit as well.
I hope the issue can be addressed and will appreciate if anyone has a workaround for this to let me know.
Thanks!
Activity image for custom activity is blank ever since iOS 17 release ,compiled in Xcode 15. The image being sent is 180x180 px. Works fine in iOS 16 running earlier Xcodes.
Attached a image of the issue showing blank icons (mail and messages are the custom activities)
Anyone facing the issue?
I've run into a problem that has been giving me fits for a while and have yet to be able to find a solution. We have a Catalyst app that uses a three-pane UISplitView. The middle and third panes show the navigation bar of the UINavigationController hosted in each pane.
However, when building under Xcode 15, the navigation bar is not shown in the middle pane when running under macOS 14. It is shown, as expected, when the app is run under prior versions of macOS. It also appears as it should under macOS 14 if the app is built with Xcode 14.
If you push another view controller onto the navigation controller's stack with the animate flag set to true, the navigation bar will appear. When you go back to the root controller, the navigation bar is present as it should be. However, if you push the controller with the animate flag set to false, the navigation bar does not appear.
I've been able to reproduce this in an isolated test app with just the relevant components. The first screenshot at the end is from a test app that illustrates the problem. The second screenshot shows what it should look like (and does look like under macOS 13).
It should be noted that UINavigationBar.appearance().preferredBehavioralStyle = .pad is set.
If any Apple folk would kindly like to look into this, I created a feedback for it: FB13260893. The feedback entry has a sample app, screenshots, and even a screen recording demonstrating the problem.
Has anyone else run into this or does anyone have any suggestions for a fix/workaround?
Thanks,
Kevin
I am using AVCaptureSession to acquire images as needed and visualize them in UIImageView.
I rotate the device while capturing and the UI automatically fits with the auto-layout effect, but the visualized image no longer fits. iOS16 rotates the image correctly and the aspect ratio fits correctly.
Even if the image is corrupted, it is displayed with the correct aspect ratio when the ViewController is moved and returned.
As a workaround, it was possible to rebuild the UIImageView when rotating the screen, but I don't think this is a good solution.
I imagine that the UIImageView cache from iOS17 is causing the problem, but is there any good countermeasure?
Thanks!
Prior to macOS 14, a Catalyst app could present a UIAlertController as a popover, just as you can on the iPad. While this still works on the iPad, the presentation on macOS now uses the same style as the iPhone.
The UIAlertController's popoverPresentationController property is always nil, no matter how it is configured.
Doe anyone know of a way to restore the prior behavior under Sonoma?
My App development language is only Arabic. I am using textField to Login User, whenever user long pressed, ToolTip showed up. Problem is with tool tip text it is flipped. My device language is English
After updating to Mac OS Sonoma, we have encountered compatibility issues with our iPad-designed application, specifically with the AirPrint functionality, when it is run on MacOS. The AirPrint feature stopped working properly through UIPrintInteractionController.shared.
We have noticed that when we compile the application using Catalyst, the AirPrint functionality is restored and works as expected. However, this solution is not viable for us due to the restrictions associated with the frameworks we are utilizing.
We are seeking alternative solutions, and any help or guidance would be highly appreciated to resolve this issue and ensure a seamless and uninterrupted user experience in our application.
STEPS TO REPRODUCE
Create an app for ipad with just a button and this code
var str = "TEST"
let printInfo = UIPrintInfo(dictionary:nil)
printInfo.outputType = .general
printInfo.jobName = "Report"
printInfo.orientation = .portrait
let printController = UIPrintInteractionController.shared
printController.printInfo = printInfo
printController.showsNumberOfCopies = false
printController.showsPageRange = false
printController.showsNumberOfCopies = false
let formatter = UIMarkupTextPrintFormatter(markupText: str)
formatter.contentInsets = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72)
printController.printFormatter = formatter
printController.present(animated: true, completionHandler: nil)
2.Run it on a MacOS with Sonoma, there is no error on console or anything but it don't work.
-If you run it with Catalyst it just works when adding the Printing permission of App Sandbox in Signing & Capabilities.
I am running into an exception whenever I try to open the app's window in visionOS simulator. The exception error message says:
"Thread 1: "Error in UIKit client: window visibility must match its layer visibility!""
This is the same code that runs just fine on iOS where I setup the app's window and tab bar controller in code:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Setup the UI - Override point for customization after app launch
UIWindowScene *firstScene = (UIWindowScene *) [[[[UIApplication sharedApplication] connectedScenes] allObjects] firstObject];
self.mainWindow = [[UIWindow alloc] initWithWindowScene:firstScene];
self.mainWindow.backgroundColor = [UIColor systemBackgroundColor];
self.tabController = [[UITabBarController alloc] init];
[self.tabController definesPresentationContext];
self.mainWindow.rootViewController = self.tabController;
[self.mainWindow makeKeyAndVisible];
// setup the tab bar later
The exception comes from the makeKeyAndVisible line. I'm not sure what I need to do differently for a visionOS app to make it work.
I'm using Xcode 15.1 Beta 2.
It appears that we are not able to reorder rows in our tables when running our iOS/iPadOS app under Mac Catalyst. It appears that all the delegate methods are returning true indicating the row can be moved and edited. The reordering handles appear in editing move and the row can be moved around (also using drag and drop) but the user interface is not indicating that the row can be dropped to be reordered. It's as if the proposed destination path is being rejected. I tried setting up that delegate method (thinking that maybe the default for that is messed up on Mac Catalyst) but it had no effect. Every table in our system performs this way.
Here is a link to an example video that shows the table view not working:
https://onsongapp.s3.amazonaws.com/Reordering%20Example.mp4
Please advise if there is something else that needs to be implemented or changed for Mac Catalyst to properly handle table cell reordering.
Accessibility is disabled for tableview cell but it is getting selected.Tableview cell is added as a subview to a view and its accessibility is also disabled.The accessibility value is coming as empty string instead of nil.Imageview is placed inside the tableview cell for that also the accessibility is disabled, still it is getting selected for the cell.Attached the view hierarchy of tableviewcell
Sample code:
BOOL voiceAccessibility = [screenDelegate getApplicationHasVoiceAccessibility];
if (voiceAccessibility) {
if (accEnabled)
{
[self setIsAccessibilityElement:YES];
if (accLable != nil && accLable.length >0)
[self setAccessibilityLabel:accLable];
}
else
{
[self setIsAccessibilityElement:NO];
self.accessibilityTraits = UIAccessibilityTraitNone;
}
}
Alternative Code tried:
-(NSString *)accessibilityLabel{
if([m_acclabel isEqualToString:@""] || m_acclabel == nil ||
m_acclabel.length == 0){
return nil;
}
return m_acclabel;
}
Accessibility Inspector Hierarchy:
PDF is successfully open in UIDocumentInteractionController but when I tap on share > Print button then app crashes only in iOS 17.0.3 (not tried in iOS 17).
It is working fine in iOS 15.8.
Crash report
"termination" : {"flags":0,"code":6,"namespace":"SIGNAL","indicator":"Abort trap: 6","byProc":"PocketRetail","byPid":341},
"ktriageinfo" : "VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter\nVM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter\nVM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter\nVM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter\nVM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter\n",
"asi" : {"libsystem_c.dylib":["abort() called"]},
"lastExceptionBacktrace" : [{"imageOffset":972256,"symbol":"__exceptionPreprocess","symbolLocation":164,"imageIndex":22},{"imageOffset":179200,"symbol":"objc_exception_throw","symbolLocation":60,"imageIndex":20},{"imageOffset":1516452,"symbol":"-[NSException initWithCoder:]","symbolLocation":0,"imageIndex":22},{"imageOffset":80840,"symbol":"-[UIViewController __supportedInterfaceOrientations]","symbolLocation":808,"imageIndex":24},{"imageOffset":7131796,"symbol":"-[_UIFullscreenPresentationController _prepareForMixedOrientationTransitionIfNecessaryInWindow:fromViewController:toViewController:]","symbolLocation":448,"imageIndex":24},{"imageOffset":7131100,"symbol":"-[_UIFullscreenPresentationController _adjustOrientationIfNecessaryInWindow:forViewController:preservingViewController:]","symbolLocation":932,"imageIndex":24},{"imageOffset":562208,"symbol":"-[UIPresentationController _presentWithAnimationController:inWindow:interactionController:target:didFinish:]","symbolLocation":524,"imageIndex":24},{"imageOffset":7825936,"symbol":"-[UIViewController _presentViewController:modalSourceViewController:presentationController:animationController:interactionController:completion:]","symbolLocation":1156,"imageIndex":24},{"imageOffset":7836224,"symbol":"-[UIViewController _presentViewController:withAnimationController:completion:]","symbolLocation":3284,"imageIndex":24},{"imageOffset":7838832,"symbol":"__63-[UIViewController _presentViewController:animated:completion:]_block_invoke","symbolLocation":92,"imageIndex":24},{"imageOffset":7839596,"symbol":"-[UIViewController _performCoordinatedPresentOrDismiss:animated:]","symbolLocation":484,"imageIndex":24},{"imageOffset":7838680,"symbol":"-[UIViewController _presentViewController:animated:completion:]","symbolLocation":188,"imageIndex":24},{"imageOffset":7839784,"symbol":"-[UIViewController presentViewController:animated:completion:]","symbolLocation":164,"imageIndex":24},{"imageOffset":299640,"symbol":"-[UIPrintPanelViewController presentPrintPanelAnimated:hostingScene:]","symbolLocation":944,"imageIndex":31},{"imageOffset":25464,"symbol":"__80-[UIPrintInteractionController _presentAnimated:hostingScene:completionHandler:]_block_invoke_2","symbolLocation":204,"imageIndex":31},{"imageOffset":68892,"symbol":"-[UIPrintInteractionController _ensurePDFIsUnlockedFirstAttempt:completionHandler:]","symbolLocation":384,"imageIndex":31},{"imageOffset":24440,"symbol":"-[UIPrintInteractionController _presentAnimated:hostingScene:completionHandler:]","symbolLocation":620,"imageIndex":31},{"imageOffset":460048,"symbol":"-[UIPrintActivity performActivity]","symbolLocation":272,"imageIndex":32},{"imageOffset":449908,"symbol":"-[SHSheetActivityPerformer _performPresentationWithViewController:]","symbolLocation":452,"imageIndex":32},{"imageOffset":1218716,"symbol":"-[UIPresentationController transitionDidFinish:]","symbolLocation":1096,"imageIndex":24},{"imageOffset":1217384,"symbol":"__56-[UIPresentationController runTransitionForCurrentState]_block_invoke.111","symbolLocation":336,"imageIndex":24},{"imageOffset":1216900,"symbol":"-[_UIViewControllerTransitionContext completeTransition:]","symbolLocation":116,"imageIndex":24},{"imageOffset":544956,"symbol":"__UIVIEW_IS_EXECUTING_ANIMATION_COMPLETION_BLOCK__","symbolLocation":36,"imageIndex":24},{"imageOffset":542804,"symbol":"-[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:]","symbolLocation":624,"imageIndex":24},{"imageOffset":540364,"symbol":"-[UIViewAnimationState sendDelegateAnimationDidStop:finished:]","symbolLocation":436,"imageIndex":24},{"imageOffset":418968,"symbol":"-[UIViewAnimationState animationDidStop:finished:]","symbolLocation":196,"imageIndex":24},{"imageOffset":419244,"symbol":"-[UIViewAnimationState animationDidStop:finished:]","symbolLocation":472,"imageIndex":24},{"imageOffset":468844,"symbol":"run_animation_callbacks(void*)","symbolLocation":132,"imageIndex":33},{"imageOffset":17152,"symbol":"_dispatch_client_callout","symbolLocation":20,"imageIndex":21},{"imageOffset":76184,"symbol":"_dispatch_main_queue_drain","symbolLocation":984,"imageIndex":21},{"imageOffset":75184,"symbol":"_dispatch_main_queue_callback_4CF","symbolLocation":44,"imageIndex":21},{"imageOffset":227772,"symbol":"__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__","symbolLocation":16,"imageIndex":22},{"imageOffset":214728,"symbol":"__CFRunLoopRun","symbolLocation":1996,"imageIndex":22},{"imageOffset":212504,"symbol":"CFRunLoopRunSpecific","symbolLocation":608,"imageIndex":22},{"imageOffset":13804,"symbol":"GSEventRunModal","symbolLocation":164,"imageIndex":23},{"imageOffset":2290428,"symbol":"-[UIApplication _run]","symbolLocation":888,"imageIndex":24},{"imageOffset":2287928,"symbol":"UIApplicationMain","symbolLocation":340,"imageIndex":24},{"imageOffset":156240,"symbol":"main","symbolLocation":60,"imageIndex":15},{"imageOffset":23876,"symbol":"start","symbolLocation":2104,"imageIndex":25}],