Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Construct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.

UIKit Documentation

Posts under UIKit subtopic

Post

Replies

Boosts

Views

Activity

How is UITextInputContext meant to be used?
At a WWDC24 consultation with the keyboards and input team, I was referred to the UITextInputContext class for detecting hardware keyboard status. However, it's not obvious how this class is intended to be used. I would like to receive notifications when the UITextInputContext state changes, however, I see no way to accomplish this. I've tried using KVO to observe state changes of the current property of UITextInputContext.class or the hardwareKeyboardInputExpected property of UITextInputContext.current, but receive no change notifications when a USB hardware keyboard is attached/detached, and hit an assertion when trying to stop observing, indicating that the observer is not registered. So I don't think KVO works. I am interested in knowing whether a hardware keyboard is attached when the virtual onscreen keyboard is hidden or shown (which occurs when the hardware keyboard is attached/detached), so that I may adjust the state of my inputAccessoryView accordingly (it should be hidden when a hardware keyboard is attached). I've had some success checking the state of UITextInputContext.current.hardwareKeyboardInputExpected during keyboard willHide/willShow notifications (or in a block executed via dispatch_async()), however, it seems that the property value does not change until the first key press after attaching a hardware keyboard, or after the first virtual onscreen key press after detaching a hardware keyboard. The latter is problematic because there are no more keyboard hide/show notifications in which to perform the needed update to my inputAccessoryView UI after the UITextInputContext state change occurs following hardware keyboard disconnection. Perhaps it's meant that I should monitor key press events and check the status there instead?
Topic: UI Frameworks SubTopic: UIKit
0
0
362
Jun ’24
Black frames in recorded videos
While using the native AVfoundation for recording videos I am able to see black frames/ screen in the beginning and end of the video for 2 millisecond at the end and beginning . func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { guard isRecording, let assetWriter = assetWriter else { return } let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) if recordingStartTime == nil { recordingStartTime = timestamp let adjustedStartTime = CMTimeAdd(timestamp, CMTimeMake(value: -2, timescale: 1000)) // Adjust start time slightly earlier assetWriter.startSession(atSourceTime: adjustedStartTime) print("Status: \(assetWriter.status.rawValue)") } if output == videoOutput { if videoInput?.isReadyForMoreMediaData == true { videoInput?.append(sampleBuffer) } } else if output == audioOutput { if audioInput?.isReadyForMoreMediaData == true { audioInput?.append(sampleBuffer) } } if let startTime = recordingStartTime, CMTimeSubtract(timestamp, startTime) >= recordingInterval { isRecording = false let adjustedEndTime = CMTimeAdd(timestamp, CMTimeMake(value: 2, timescale: 1000)) // Adjust end time slightly later assetWriter.finishWriting { [weak self] in print("Finished writing segment") self?.startRecording() // Start a new recording segment } recordingStartTime = nil } }
1
1
721
Jun ’24
UITabBarController render glitch since iOS18 beta 1 & 2 when activating tabs.
We have a UITabBarController in our iPhone App which has 5 tabs with UITableViewControllers (constructed from the storyboard). Before iOS18 beta 1 (and 2) this was working fine without any problems (objective-C). Since iOS18 beta 1 (and beta 2 still has this problem) a strange render glitch occurs when activating a tab from the tab bar at the bottom. As soon as a tab is activated (by tapping on the icon at the bottom) the tab with the UITableViewController becomes visible and draws its content starting at the very top of the screen (pos 0,0) right through/over the Navigation bar which at that point is showing a title and a rightBarButtonItem. The tab with the UITableViewController seems not aware there is a navigation bar visible. Then after ~0.3 seconds the tab with the UITableViewContoller is automatically rendered again or moved down and now its content starts below the UINavigationBar as expected, this is 100% reproducible and occurs on every activation of a tab in the UITabBarController. Is anyone else also getting this behavior in their App since iOS18? I'm aware that UITabBarController is being renewed but I can't find any information on why this behavior might occur. I was hoping beta 2 would solve the problem but it doesn't. Constructing the UITabBarController in the code with the new UITab objects (instead of constructing them from the storyboard) also shows this problem.
5
1
1.3k
Jun ’24
iOS 18 Translation API availability for UIKit
After reading the documentation for TranslationSession and other API methods I got an impression that it will not be possible to use the Translation API with UI elements built with UIKit. You don’t instantiate this class directly. Instead, you obtain an instance of it by adding a translationTask(_:action:) or translationTask(source:target:action:) function to the SwiftUI view containing the content you want to translate So the main question I have to the engineers of mentioned framework is will there be any support for UIKit or app developers will have to rewrite their apps in SwiftUI just to be able to use the Translation API?
1
1
1.9k
Jun ’24
Any way to have UIBlurEffectView ignor views below it?
Is there any way to have a UIBlurEffectView ignore views underneath it? More than just masking it. Mask of a view below it, it'll still process that view and you'll still see a "halo" around the edge. Ideally I'd like to have a view 'below' the blur, mask it, and also not have the view be processed in the blur.
Topic: UI Frameworks SubTopic: UIKit
1
0
326
Jun ’24
Spring Animations with Constraints don't behave properly
Repo is here Visual Description is here: Basically the red view should never be inside the blue view. The red view has a fixed aspect ratio. The blue view initially has an aspect ratio different from the red view and is animated to have the same aspect ratio. The red view is constrained inside the blue view as follows: let ac = brokenView.widthAnchor.constraint(equalTo: brokenView.heightAnchor, multiplier: 9/16) let xc = brokenView.centerXAnchor.constraint(equalTo: animView.centerXAnchor) let yc = brokenView.centerYAnchor.constraint(equalTo: animView.centerYAnchor) let widthC = brokenView.widthAnchor.constraint(equalTo: animView.widthAnchor) widthC.priority = .defaultLow let gewc = brokenView.widthAnchor.constraint(greaterThanOrEqualTo: animView.widthAnchor) let geHC = brokenView.heightAnchor.constraint(greaterThanOrEqualTo: animView.heightAnchor) geHC.priority = .required So the red view should start at equal width, but prioritize always been taller and wider than the blue view while staying centered and keeping a fixed aspect ratio. As you can see in the visual description it is not priortizing being taller. Any suggestions on how to fix, work around, or otherwise get past this would be appreciated. Really trying to avoid manually doing a spring animation with keyframes and an assload of math. I have filed a bug on feedback assistant, but figured someone here might have experience//know how. Thanks
0
0
685
Jun ’24
iOS 16 Crash (EXC_BAD_ACCESS (KERN_INVALID_ADDRESS))
I have a project with 2-5k daily online users, but have only 5 users that have this crashes. They all have iOS 16 installed Attached logs from FireBase First Log: Crashed: com.apple.main-thread 0 libobjc.A.dylib 0x1c20 objc_msgSend + 32 1 UIKitCore 0x9bd754 -[UIView _backing_traitCollectionDidChange:] + 64 2 UIKitCore 0x169754 -[UIView _traitCollectionDidChangeInternal:] + 628 3 UIKitCore 0x1692b4 -[UIView _wrappedProcessTraitCollectionDidChange:forceNotification:] + 156 4 UIKitCore 0x169424 -[UIView _wrappedProcessTraitCollectionDidChange:forceNotification:] + 524 5 UIKitCore 0x927e8 -[UIView(AdditionalLayoutSupport) _withUnsatisfiableConstraintsLoggingSuspendedIfEngineDelegateExists:] + 96 6 UIKitCore 0x90cac -[UIView _processDidChangeRecursivelyFromOldTraits:toCurrentTraits:forceNotification:] + 212 7 UIKitCore 0x43d0 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1732 8 QuartzCore 0x97fc CA::Layer::layout_if_needed(CA::Transaction*) + 500 9 QuartzCore 0x1ceb0 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 148 10 QuartzCore 0x2e234 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 444 11 QuartzCore 0x63630 CA::Transaction::commit() + 652 12 UIKitCore 0x3c49c4 -[_UISceneLifecycleMultiplexer collectBackingStores] + 28 13 UIKitCore 0x3c4988 __35-[UIWindowScene _prepareForSuspend]_block_invoke + 40 14 UIKitCore 0x3026dc -[_UIContextBinder purgeContextsWithPurgeAction:afterPurgeAction:] + 388 15 UIKitCore 0x21053c -[UIWindowScene _prepareForSuspend] + 80 16 UIKitCore 0x20ebb8 -[UIScene _emitSceneSettingsUpdateResponseForCompletion:afterSceneUpdateWork:] + 752 17 UIKitCore 0x20e810 -[UIScene scene:didUpdateWithDiff:transitionContext:completion:] + 244 18 UIKitCore 0x20e650 -[UIApplicationSceneClientAgent scene:handleEvent:withCompletion:] + 336 19 FrontBoardServices 0x366c -[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:] + 420 20 FrontBoardServices 0x34a8 __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke_2 + 144 21 FrontBoardServices 0x6c24 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 168 22 FrontBoardServices 0x6b40 __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke + 340 23 libdispatch.dylib 0x3f88 _dispatch_client_callout + 20 24 libdispatch.dylib 0x7a08 _dispatch_block_invoke_direct + 264 25 FrontBoardServices 0x10d40 FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK + 52 26 FrontBoardServices 0x108dc -[FBSSerialQueue _targetQueue_performNextIfPossible] + 220 27 FrontBoardServices 0x13184 -[FBSSerialQueue _performNextFromRunLoopSource] + 28 28 CoreFoundation 0xd5f24 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 28 29 CoreFoundation 0xe22fc __CFRunLoopDoSource0 + 176 30 CoreFoundation 0x661c0 __CFRunLoopDoSources0 + 244 31 CoreFoundation 0x7bb7c __CFRunLoopRun + 836 32 CoreFoundation 0x80eb0 CFRunLoopRunSpecific + 612 33 GraphicsServices 0x1368 GSEventRunModal + 164 34 UIKitCore 0x3a1668 -[UIApplication _run] + 888 35 UIKitCore 0x3a12cc UIApplicationMain + 340 36 Vostok 0x1e36ec main + 10 (main.swift:10) 37 ??? 0x1ac74c960 (Missing) All this crashed happened on background Can't reproduce on own iPhone, because haven't 16 iOS
Topic: UI Frameworks SubTopic: UIKit
0
0
290
Jun ’24
Workout session active but "Return to app" option not displayed in menu
I have an iOS app, with a watch counterpart, used to enter scores for a match. The watch app starts a match (and a workout session) when it receives a notification from the mobile app, after the user started a match on their phone. Basically the watch app is just a more convenient way of inputing scores, so the user wouldn't have to reach for and unlock their phone every time - therefore the need for the watch app to always be displayed. The flow follows these steps: the user is prompted for workout session access when first launching the app; after they accept, I start the workout; the delegate method workoutSession(didChangeTo) returns the expected values; the app remains active, even when the user lowers their wrist; when I go to the clock, the app's icon is displayed in a circle at the top (bringing the app back to foreground on tap). The only problem is that the "Return to app" option in the "Return to Clock" settings menu is missing, what do I need to do in order to display it? Here's an example of what it looks like for the Strava app: and how it looks for mine.
0
1
600
Jun ’24
Cordova based app not working after updating iOS to 17.5.1
After updating iOS, my Cordova app behaves incorrectly after receiving a voip push. When a push notification is received, my application launches CallKit, displays the Native Dialer screen and starts other necessary services. Until 17.5.1 (possibly 17.5) everything worked correctly. All services and sockets were established/ connected and working. After updating iOS to 17.5, the application crashes, and while voice connection is established the app is no longer active. Xcode logs have these error messages: Invalidating grant <invalid NS/CF object> failed Type: Error | Timestamp: 2024-06-20 13:27:44.719601+02:00 | Process: MyApp | Library: WebKit | Subsystem: com.apple.WebKit | Category: ProcessCapabilities | TID: 0x3a4929 Invalidating grant <invalid NS/CF object> failed Type: Error | Timestamp: 2024-06-20 13:27:44.732219+02:00 | Process: MyApp | Library: WebKit | Subsystem: com.apple.WebKit | Category: ProcessCapabilities | TID: 0x3a4929 Invalidating grant <invalid NS/CF object> failed Type: Error | Timestamp: 2024-06-20 13:27:44.733996+02:00 | Process: MyApp | Library: WebKit | Subsystem: com.apple.WebKit | Category: ProcessCapabilities | TID: 0x3a4929 I am using: Cordova iOS: 6.2 iOS 17.5.1 Can anyone please help?
8
1
5.7k
Jun ’24
Fatal Exception: NSInvalidArgumentException Application tried to present modally a view controller <UIAlertController: 0x10786d000> that is already being presented by
We never received customer report this crash, and we could not see during development phase However we can see this crash quite often on crash analytics. I have gone through UIAlertController in code level, it always creates new one instead reusing it. Please help me identify why this occurs? Much appreciated crash_session_2ecf1bdde30e402f9df795ea7681272b_DNE_0_v2_stacktrace.txt
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
576
Jun ’24
iOS 18 beta1/2 CoreText Crash
0 libobjc.A.dylib 0x000000018e27f008 objc_msgSend + 8 (:-1) 1 CoreFoundation 0x0000000190eaa4bc -[__NSDictionaryM objectForKey:] + 168 (NSDictionaryM.m:179) 2 CoreFoundation 0x0000000190f003e8 -[NSDictionary containsKey:] + 56 (NSDictionary.m:80) 3 CoreFoundation 0x0000000190f0006c CFDictionaryContainsKey + 52 (CFDictionary.c:265) 4 libGSFont.dylib 0x00000001af98cc14 GSFontIsOverriddenSystemFontName + 32 (GSFont.m:2860) 5 CoreText 0x0000000192d6f1fc CopyAttributeForSystemFont(__CFString const*, __CFString const*) + 64 (MetadataSupport.cpp:194) 6 CoreText 0x0000000192d6edd4 AddVariationInfo(TCFMutableDictionary&, __CFString const*) + 60 (SplicedFontSupport.cpp:6760) 7 CoreText 0x0000000192de1ea0 MakeSpliceDescriptor(__CFString const*, unsigned long, __CFString const*, __CFString const*, __CFNumber const*, __CFNumber const*, unsigned int, CTFontTextStylePlatform, unsigned int, __CFNumber co... + 4504 (SplicedFontSupport.cpp:7429) 8 CoreText 0x0000000192ddd374 TDescriptorSource::CopySpliceFontForName(__CFString const*, __CFString const*, __CFNumber const*, __CFNumber const*, CTFontLegibilityWeight, __CFBoolean const*, __CFNumber const*, __CFString const*... + 1376 (TDescriptorSource.cpp:4288) 9 CoreText 0x0000000192dda800 TDescriptorSource::CopySplicedDescriptorForName(__CFString const*, __CFString const*, __CFString const*, __CFNumber const*, __CFNumber const*, CTFontLegibilityWeight, __CFBoolean const*, __CFNumber... + 172 (TDescriptorSource.cpp:4322) 10 CoreText 0x0000000192d0a214 TDescriptor::CreateMatchingDescriptorInternal(__CFSet const*, unsigned long) const + 2332 (TDescriptor.cpp:804) 11 CoreText 0x0000000192d09148 TDescriptor::InitBaseFont(unsigned long, double) + 76 (TDescriptor.cpp:952) https://feedbackassistant.apple.com/feedback/14091158
4
1
1.2k
Jun ’24
The HEIC images in the Assets folder are displaying abnormally
I placed a PNG format image in the Assets folder and also added a HEIC format image that was converted from PNG. When the slicing is set to None, both images appear the same in the UIImageView. However, when I select "Horizontal and Vertical" for the Slices of both images, they no longer appear consistent, and the HEIC image displays abnormally. @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self addImageViews]; } - (void)addImageViews { UIImageView *heicImageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, [self imageViewSize].width,[self imageViewSize].height)]; UIImageView *pngImageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 300, [self imageViewSize].width,[self imageViewSize].height)]; heicImageView.image = [UIImage imageNamed:@"heic"]; pngImageView.image = [UIImage imageNamed:@"png"]; [self.view addSubview:heicImageView]; [self.view addSubview:pngImageView]; } - (CGSize)imageViewSize { return CGSizeMake(146, 44); } @end
Topic: UI Frameworks SubTopic: UIKit
1
0
321
Jun ’24
UIDocument related hang in OS code
Hi A user of my app has contacted me about a crash they’re getting. They’ve sent me some logs (see attached) but I’m having difficulty working out what the cause is as it looks like it’s a watchdog timeout that’s occurring inside OS code, not my application. I also can’t reproduce the crash locally. App background info: The app logs peoples skydives, each log can contain a lot of data (rotation rates, acceleration, location, speeds, etc) and is stored in a separate file. These files can be stored in an iCloud container so the logs can be viewed from different devices. I use CoreData to maintain a database of key metadata so I can list the jumps in the UI even if the file for a jump isn’t on the device. Occasionally I have to delete this database and rebuild it by loading each jump log file and getting a fresh copy of the metadata. EG this can happen if a new version of the app requires an additional metadata field in the database. Crash info: The crash looks like it’s happening rebuilding the database, so the app will be trying to download and open each jump log and add the records to the database. I’ve noticed the following odd things about the crash log, which might be a good place to start: There’s a huge number of threads in the “”UIDocument File Access” dispatch queue that are blocked It looks like there's exactly 512 threads blocked in this queue. Which makes me think its hitting a limit. Any idea why they are blocked? I don’t know why there are so many, The database rebuild is done from an operation queue with a max concurrency of 10. So I would expect at most 10 jump logs to be being opened at one time There seams to be two common stack trace patterns. Eg compare thread 1 and thread 5 in crash log 1. In both crash logs the main thread is blocked, but in different bits of OS code in the two crash logs. It looks like this is the cause of the watchdog failure, but I’m not sure what the common cause could be. Any ideas / help would be really appreciated. Thanks Tom NOTE: I had to cut down the crash logs so they were small enough to upload. Crash log 1 small.txt Crash log 2 small.txt
0
0
399
Jun ’24
iOS 18. UINavigationController stack changes with delay
If I do something like this: var viewControllers = navigationController.viewControllers if let lastViewController = viewControllers.popLast() { navigationController.viewControllers = viewControllers navigationController.pushViewController(lastViewController, animated: false) } } I got crash: pushing the same view controller instance more than once If I set delay: var viewControllers = navigationController.viewControllers if let lastViewController = viewControllers.popLast() { navigationController.viewControllers = viewControllers DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { navigationController.pushViewController(lastViewController, animated: false) } } it will work but with unnecessary transitions. Should it work like this in iOS 18 ?
2
3
1.4k
Jun ’24
Text selection doesn't work in WKWebView on macOS Sonoma
Can not select anything within WkWebView editor view of my MacCatalyst app when running on macOS 14 Sonoma. Any selection gesture or command key fails to select anything in content editable WKWebView, so none of the Editor tools can be activated. My application uses the nnhubbard / ZSSRichTextEditor WKWebView-based Rich Text Editor: https://github.com/nnhubbard/ZSSRichTextEditor. The app is built with Xcode 15.4. The app is a Catalyst app that implements an editor view with a ZSSRichTextEditor WKWebView. The problem does not occur if the the app is run in macOS 11, 12, or 13 (Catalina, Monterey, or Ventura.) The issue only occurs in macOS 14 Sonoma. The following error message is logged whenever an attempt to select any text in the WKWebView content: 0x1359ecc18 - [pageProxyID=14, webPageID=15, PID=14,932] WebPageProxy::didFailProvisionalLoadForFrame: frameID=1, isMainFrame=1, domain=NSURLErrorDomain, code=18,446,744,073,709,550,614, isMainFrame=1, willInternallyHandleFailure=0 Without the ability to select text the editor (WKWebView) is useless since no editing tool can be invoked without a selection. An Apple Feedback report was filed: FB13344011. An incident was filed with DTS concerning this issue. Apple Developer Technical Support's reply was "Our engineers have reviewed your request and have determined that you are experiencing a known issue for which there is no known workaround at this time." Since DTS’ reply there has been no further response from them.
Topic: UI Frameworks SubTopic: UIKit
7
1
948
Jun ’24
UIKit MacCatalyst - How to drag a table view item to Finder to create a folder of items
I have a UITableView that displays a Group/Note hierarchy analogous to a Finder Folder/Files hierarchy. I have implemented Drag and Drop such that if I drag a Note to the Finder Desktop an HTML file is created of the Note, and if I drag a Group to the Finder Desktop a Text file is created of the Group's title. Here is the Helper Dragging extension that I've implemented: // // Model+Dragging.swift // /* Abstract: Helper methods for providing and consuming drag-and-drop data. */ import UIKit import MobileCoreServices // Conditionalize Drag and Drop so it is not in iOS target. #if targetEnvironment(macCatalyst) extension Model { /** A helper function that serves as an interface to the data model, called by the implementation of the `tableView(_ canHandle:)` method. */ func canHandle(_ session: UIDropSession) -> Bool { // In order to enable dragging all text type files changed the class // loadable objects from NSString to my custom TEXTClass. return session.canLoadObjects(ofClass: TEXTClass.self) } /** A helper function that serves as an interface to the data model, called by the `tableView(_:itemsForBeginning:at:)` method. */ func dragItems(for indexPath: IndexPath) -> [UIDragItem] { let itemProvider = NSItemProvider() let item = self.getDisplayItem(for: indexPath.row) if item is Note { let note:Note = item as! Note let html = note.noteHTML let data = html?.data(using: .utf8) // Drag to finder creates an html file. itemProvider.suggestedName = note.title + ".html" itemProvider.registerDataRepresentation(forTypeIdentifier: kUTTypeData as String, visibility: .all) { completion in completion(data, nil) return nil } } else { let group:Group = item as! Group let title = group.title let data = title?.data(using: .utf8) // Drag to finder creates a text file. itemProvider.suggestedName = group.title + ".text" itemProvider.registerDataRepresentation(forTypeIdentifier: kUTTypeData as String, visibility: .all) { completion in completion(data, nil) return nil } } return [ UIDragItem(itemProvider: itemProvider) ] } } #endif I would now like to change the result of dragging a Group to the Finder. Instead of creating a Text file from the drag data, I would like to create a Folder containing the Group's Notes. Note: I am unconcerned with the task of assembling the Group/Notes hierarchies as Folder/Files hierarchies because I already have implemented such previously as a menu export command. My concern is where and how I can communicate it to the Finder in the Drag and Drop process. As a first step I thought I would simply create an empty folder from the drag of a Group. So far, none of my experiments have been successful. Every variation of itemProvider.registerDataRepresentation(forTypeIdentifier: or itemProvider.registerFileRepresentation(forTypeIdentifier: or registerItem(forTypeIdentifier:loadHandler: that I have tried has failed to produce anything but empty TEXT files, if they worked at all. It is my understanding that itemProviders may provide directories instead of files, but I have been unable to find any examples of such. My problem may be a lack of understanding of the syntax and usage of the NSItemProvider.LoadHandler completion block. Any Swift examples on point would be greatly appreciated!
1
0
688
Jun ’24
UI Tab Bar
Anyone else get these warnings when using UI Tab Bar in visionOS? Are these detrimental to pushing my visionOS app to the App Review Team? import SwiftUI import UIKit struct HomeScreenWrapper: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> UITabBarController { let tabBarController = UITabBarController() // Home View Controller let homeVC = UIHostingController(rootView: HomeScreen()) homeVC.tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), tag: 0) // Brands View Controller let brandsVC = UIHostingController(rootView: BrandSelection()) brandsVC.tabBarItem = UITabBarItem(title: "Brands", image: UIImage(systemName: "bag"), tag: 1) tabBarController.viewControllers = [homeVC, brandsVC] return tabBarController } func updateUIViewController(_ uiViewController: UITabBarController, context: Context) { // Update the UI if needed } } struct HomeScreenWrapper_Previews: PreviewProvider { static var previews: some View { HomeScreenWrapper() } }
1
0
663
Jun ’24
Displaying HDR image, isn't showing dynamic range
I'm playing around with HDR images in iOS. I'm able to load an HDR image, but it isn't displaying with the expected "pop" I see of the same image in the Photos app. I exported the photo from Photos (on the Mac) using Export Unmodified. I reimported to confirm Photos shows the "pop." I'm trying both UIImage and CIImage, with the same results. The below is tested on my iPhone 14 Pro (not Simulator). The Storyboard for the code below has three UIImageViews (top, middle, and bottom). let fileURL = Bundle.main.url(forResource: "IMG_6972", withExtension:"HEIC")! var config = UIImageReader.Configuration() config.prefersHighDynamicRange = true let imageReader = UIImageReader(configuration: config) let topImage = imageReader.image(contentsOf: fileURL)! topImageView.preferredImageDynamicRange = .high topImageView.image = topImage // The image appears, looks SDR print("topImage.isHighDynamicRange: \(topImage.isHighDynamicRange)") // true let ciimage = CIImage(contentsOf: fileURL)! bottomImageView.image = UIImage(ciImage: ciimage) // The image appears, looks SDR - identical to topImage print("color space: \(ciimage.colorSpace!)") // (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Display P3) let gainMap = CIImage(contentsOf: fileURL, options: [.auxiliaryHDRGainMap: true])! middleImageView.image = UIImage(ciImage: gainMap) // The gain map image appears as expected Additionally, for comparison, I tried: let sdrImage = UIImage(named: "IMG_6972.HEIC")! // UIImage.named doesn't support HDR print("sdrImage.isHighDynamicRange: \(sdrImage.isHighDynamicRange)")``` // false, as expected bottomImageView.image = sdrImage and the image matches the other two, further confirming the HDR version of the image isn't displaying in either UIImageReader or CIImage versions above. I also track the UIScreen's use of EDR with: print("currentEDR: \(UIScreen.main.currentEDRHeadroom)") print("maxEDR: \(UIScreen.main.potentialEDRHeadroom)") maxEDR is 8.0. currentEDR is 1.0 at launch, 1.3 after a 1.0 second delay. Which makes me think it might be showing a little HDR, but not enough to be noticeable. Is there something special I need to do to set the UIViewController, UIScreen, or UIApplication (etc) to be an an "HDR Mode" or similar?
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
1k
Jun ’24