Post

Replies

Boosts

Views

Activity

UITabBar in iOS 26 is Too Big for Touch ID Devices
I do the majority of my test development on an iPhone 16 Pro in the iOS Simulator. As part of my UI rework to maintain compatibility with iOS 26 I decided to run on an older device with a small screen size for testing. The smallest device that supports iOS 26 is the iPhone SE 2nd Gen and 3rd Gen. Take a look at the image below: On the left is the iPhone SE 2nd Gen. On the right iPhone 16 Pro. It looks like the UITabBar which is from a UITabBarController is sized too tall. The actual Tab Bar itself is 62px while the container that houses it is 83px. Yes there should be some top/bottom space to allow for the Liquid Glass Effect to overlap as it often spills outside it's bounds but this feels like far too much. Looking at them side by side, the iPhone SE Tab Bar actually takes up more space which is not ideal for users who are working on a smaller screen to begin with and have less real estate. It looks like the bottom space is allowable room for the 'swipe to dismiss line' however these devices use Touch ID and that line is never present. Feels like the 83px for the Tab Bar should be reduced on these devices to allow for more useable screen real estate. Is this a design oversight as iOS 26 seems to be built predominantly for Face ID Devices? Just wondering if any Apple Design Engineers can chime in to see if this will be addressed in a future beta? The only way to change it at this stage is with a CGAffineTransform however this does not impact the '_UITabBarContainerWrapperView' that sits behind it. Also, on that note. The '_UITabBarContainerWrapperView' sometimes seems to be clear and other times displays a solid system background color. Is there anyway to control this? Many of my views both SwiftUI and UIKit have differing behaviour. My understanding is the idea of iOS 26 is for your app's content to be visible behind the Tab Bar, however the content is obscured by '_UITabBarContainerWrapperView' in many of my views and I can not figure out how to change that. Thanks!
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
105
3w
Detents Size Differently on Touch ID Devices in iOS 26
When working with modal sheet views in iOS 26 I animate changes to detent size like this: if let sheet = self.sheetPresentationController { let newDetent = 400 sheet.animateChanges { sheet.invalidateDetents() sheet.detents = [.custom(resolver: { context in newDetent })] } } What I have found is that when using a Touch ID Device the input detent will be smaller when the system presents it. If I set the detent size to be 400, on an iPhone 16 Pro it will be 400px but on an iPhone SE 2nd Gen it will be 366. It seems to be consistently 34px shorter on devices with a Touch ID Square Shaped Screen. This 34px corresponds to the bottom safe area. This feels like a bug to me. I would expect the detent size to match what I assign on all devices. I will monitor if this is fixed in a future beta but it is present as of iOS 26 Beta 5. In the meantime I have built this helper function which will then correctly size it on all devices: static func getDetent(basedOn inputValue: Double) -> CGFloat { if let window = UIApplication.shared.windows.first { if window.safeAreaInsets.bottom > 0 { // Face ID Device, Bottom Inset of 34 return inputValue } else { // Touch ID Device, Bottom Inset of 0 return inputValue + 34 } } else { // Fallback, Return Input Value return inputValue } } This impacts when animating detents as per above but also when presenting a Sheet View for the first time and assigning a custom detent. Thanks!
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
62
3w
iOS 26 Beta 6 in Simulator
Is iOS 26 Beta 6 available in the iOS Simulator? I saw that the latest betas launched earlier this week. I updated my dev machine to macOS 26 Beta 6, however this release had no corresponding Xcode 26 Beta 6. So I am still running Xcode Beta 5 and when I go into Settings -> Components within Xcode there is no option to install iOS 26 Beta 6. It's still running Beta 5 for macOS and iOS. Is that correct? My current assumption is that iOS Beta 6 is for physical devices only?
1
0
117
3w
UIStoryboard.instantiateInitialViewController Not Working in iOS 18.6 When Built with iOS 26 SDK
In my SceneDelegate via 'scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)' I call the following code to assign a Storyboard: let storyboard = UIStoryboard(name: "Main", bundle: nil) let initialVC = storyboard.instantiateInitialViewController() self.window?.rootViewController = initialVC The Initial VC is a UITabBarController. The app crashes when calling 'instantiateInitialViewController': *** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named _TtGC5UIKit17UICoreHostingViewVCS_21ToolbarVisualProvider8RootView_ because no class named _TtGC5UIKit17UICoreHostingViewVCS_21ToolbarVisualProvider8RootView_ was found; the class needs to be defined in source code or linked in from a library (ensure the class is part of the correct target)' terminating due to uncaught exception of type NSException CoreSimulator 1047 - Device: iPhone 16 Pro (06A3EAF6-6623-49FD-BEFE-BE88FDD13BBE) - Runtime: iOS 18.6 (22G86) - DeviceType: iPhone 16 Pro Works fine in iOS 26 when compiling using Xcode 26. Works fine when compiling for iOS 18.6 in Xcode 16.4. Seems to just be an issue when using the iOS 26 SDK in iOS 18.6. This will be an issue for Day 01 Updates if a user hasn't updated to iOS 26 yet.
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
71
Aug ’25
Modal Presentation in UIKit Adds Solid Background in iOS 26
Hello, I have a number of UIViewControllers that are presented as follows: vc.modalPresentationStyle = UIModalPresentationStyle.popover vc.modalTransitionStyle = UIModalTransitionStyle.coverVertical self.present(vc, animated: true, completion: nil) The VC is designed from a Storyboard where I set the 'view' of the VC to have a .clear 'backgroundColor', I have a smaller 'Alert View' added as a subview which is what the user interacts with. In iOS 13 - iOS 18 this would present modally, not take up the entire screen and allow the user to see relevant context from the screen underneath. In iOS 26 Beta 5 and every beta prior the system injects a 'UIDropShadowView' in the View Hierarchy, this view has a solid color backdrop, either white/black depending on light/dark mode. This causes all underlying content to be blocked and essentially forces a full screen modal presentation despite the existing design. I am looking for a way to remove this solid color. I'm not sure if it's intentional or a bug / oversight. I have been able to remove it in a hacky way, I cycle the view hierarchy to find 'UIDropShadowView' and set it's backdrop to transparent. However when you swipe down to partially dismiss the view it turns to Liquid Glass when it is around 75% dismissed and then resets the background color to white/black. I tried creating a custom UIViewControllerTransitioningDelegate so that I could re-implement the existing behaviour but it's incredibly difficult to mimic the partial dismiss swipe down effect on the VC. I have also tried changing my presentation to: vc.modalPresentationStyle = UIModalPresentationStyle.overFullScreen vc.modalTransitionStyle = UIModalTransitionStyle.crossDissolve This works but then the user loses the ability to interactively swipe to dismiss. Any help would be appreciated. Thank you!
Topic: UI Frameworks SubTopic: UIKit Tags:
6
1
227
Aug ’25
NavigationView Issues in iOS 18 Beta 3
I have a SwiftUI NavigationView that is presented inside of a UIHostingController. In iOS 17 and earlier everything looks and works okay. I opened up my project in iOS 18 Beta 3 via the iOS Simulator running on macOS Sequoia, the NavigationView just displays a blank view with a Sidebar Button in the top left outside of the safe area. If I comment out the NavigationView and just display my 'root view' everything looks as it should but navigation is broken as it uses NavigationLink which of course doesn't work without NavigationView. I still target iOS 14 as Minimum Version so swapping completely to NavigationStack isn't possible given that NavigationView is deprecated from iOS 16 onwards. I tried to implement a solution with NavigationStack, it works but my UI displays outside of the safe area. I have a button towards the bottom of the screen which now overlaps the system line at the bottom of the screen. The Back Button in the Navigation Stack now sits behind the time in the top left. I do not have 'ignoreSafeArea' applied anywhere in this View Hierarchy. It looks like that is being applied by 'NavigationStack' on it's own accord. Is this happening to anyone else? Is this a known bug? I could not see this in the release notes if it is known. Thanks!
Topic: UI Frameworks SubTopic: SwiftUI
9
0
4.4k
Jul ’24
iOS Device Support Keylogger
Hello, I recently ran a virus/malware scan on my dev machine using ClamAV, this was run via macOS Terminal using the 'clamscan' function. Everything came back okay except a keylogger in the ProVideo Framework for physical iOS Test Devices. Please see below for 'clamscan' output: /Users/username/Library/Developer/Xcode/iOS DeviceSupport/iPad8,11 17.4 (21E219)/Symbols/System/Library/PrivateFrameworks/ProVideo.framework/ProVideo: Unix.Keylogger.Macos-10023932-0 FOUND My understanding is that '/Library/Developer/Xcode/iOS DeviceSupport/' is where Xcode keeps the files related to physical test devices that are required for debug. There were 3 Instances of this keylogger, all of which corresponded to physical devices I own and iOS Versions that I have installed / were installed. Can anyone verify if 'Unix.Keylogger.Macos-10023932-0' is a valid file that ClamAV is incorrectly detecting as malicious? If it is a valid debug file provided by Apple, it seems strange that it's located in the ProVideo Framework. I couldn't find any documentation online about this so any information would be appreciated. At this stage I have deleted the contents of '/Library/Developer/Xcode/iOS DeviceSupport/', my understanding is that these symbols are only transferred to the system when I test software via Xcode on a physical device and will not reproduce until I do that again. To me it's unclear if perhaps this keylogger is present on my iOS Device and is being transferred to the Mac via Xcode? Or somehow it is just appearing in this folder? Thanks!
2
0
3.1k
Apr ’24
Allow Display Mode Changes
When you connect an external display via USB-C to an iPad, that displays shows in iPadOS via Settings -> Display and Brightness -> Name of Display. There is an option called 'Allow Display Mode Changes' for an external display which is described as follows: When this is on, the display mode will change to match the dynamic range and frame rate of the content you're viewing. This may result in flickering or long periods of black whenever content changes. Does anyone know how this functionality works and how to support it for an iPadOS App? In my tests the iPad always outputs at a frame rate of 60fps or sometimes 59.94fps. If the video I am playing back from an AVPlayer is at 25fps the external display stays at 60fps both with 'Allow Display Mode Changes' toggled on/off. Given that it's meant to 'match frame rate of content' I would expect the external display to change from 60fps -> 25fps. I can not find any documentation about this feature and what AV Frameworks it talks to or gets it's frame rate information from. If anyone has any idea or has experimented with it and learnt something that would be much appreciated.
0
0
1.1k
Nov ’23
Weird Issue with UIDatePicker
Hello All, I've been using a UIDatePicker in my application since launch and it has been working without issue. Sometime in the past 4-6 Weeks I've had users reporting an intermittent problem where it does not work, at this stage I can not confirm if it's happening only on newer versions of the app, this shouldn't be the case as the code base has not changed at all for anything related to the UIDatePicker. I have seen it happen in the wild once on a friend's App Store Version of my app, on his iPhone he would move the UIDatePicker and the date would change in the picker view, but it wouldn't be reflected elsewhere in the app indicating that the UIDatePicker isn't sending data through to other components, in this case the UITextField. However on my device, two devices and the iOS Simulator, all on the same iOS Version, all with the latest version of the app, this issue did not occur. Code snippets are as follows: // Setup Date Picker     datePicker.datePickerMode = .date     datePicker.addTarget(self, action: #selector(AddWorkDayViewController.datePickerChanged(sender:)), for: .valueChanged)           // Set Date Picker Style     if #available(iOS 13.4, *) {       datePicker.preferredDatePickerStyle = .wheels     } else {       // Fallback on Earlier Versions     }           //Setup Date Toolbar     dateToolbar.barStyle = .default     dateToolbar.isTranslucent = true     dateToolbar.sizeToFit()     let doneButton = UIBarButtonItem(title: "done".localized(), style: .done, target: self, action: #selector(AddWorkDayViewController.doneTouched))     let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)     let todayButton = UIBarButtonItem(title: "today".localized(), style: .done, target: self, action: #selector(AddWorkDayViewController.todayTouched))     dateToolbar.setItems([todayButton, spaceButton, doneButton], animated: false)     dateToolbar.isUserInteractionEnabled = true           // Assign Date Picker and Date Toolbar to Date Label     dateLabel.inputView = datePicker     dateLabel.inputAccessoryView = dateToolbar // Called When User Changes UIDatePicker @objc func datePickerChanged(sender: UIDatePicker) {     let pickerDate = sender.date     date = pickerDate     let dateFormatted = date.toFormat(settings.dateFormatLong)     dateTextField.text = dateFormatted   } Any ideas on where to start with this? Given it happens on some devices and not others it's quite troublesome to diagnose. On the device I saw it happen on I checked accessibility settings, rebooted the device, etc. and could not figure out why it was behaving this way. Thank you!
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
1.3k
Sep ’22
Inconsistent Widget Behaviour Between Devices in iOS 14
Hello All, I recently launched an iOS 14 Widget for my app. In testing everything seemed a-okay but on launch I am having inconsistent behaviour. On some devices the widget loads as just black, on other devices it only loads the placeholder content and on some devices it works as intended. The behaviour exhibited, good or bad, is consistent in the Add Widget Screen and when it's added to the Home Screen. On the devices where my widget does not work, other widgets do work. The content in the Widget only changes when something is changed in the app thus I call WidgetCenter.shared.reloadAllTimelines() in the SceneDelegate when sceneWillResignActive is called. The expected behaviour is that when the user backgrounds the application the widget will update. On the devices that show black or placeholder content this Widget Center Update does not work, on the devices where it does work the update function works as expected. This is the code for my Widget:   struct ThisWeekProvider: TimelineProvider {     func placeholder(in context: Context) - ThisWeekEntry {       return ThisWeekEntry(date: Date(), thisWeekJSON: getDefaultTimeSummaryJSON())     }         func getSnapshot(in context: Context, completion: @escaping (ThisWeekEntry) - ()) {           var thisWeekData = TimeSummaryJSON()       if context.isPreview {         thisWeekData = getThisWeekData()       } else {         thisWeekData = getThisWeekData()       }           let entry = ThisWeekEntry(date: Date(), thisWeekJSON: thisWeekData)       completion(entry)     }         func getTimeline(in context: Context, completion: @escaping (TimelineEntry) - ()) {       let entries: [ThisWeekEntry] = [ThisWeekEntry(date: Date(), thisWeekJSON: getThisWeekData())]           let timeline = Timeline(entries: entries, policy: .after(entries[0].thisWeekJSON.endDate))       completion(timeline)     }   }       struct ThisWeekEntry: TimelineEntry {     let date: Date     let thisWeekJSON: TimeSummaryJSON   }       struct ThisWeekWidgetEntryView : View {     var entry: ThisWeekProvider.Entry     var body: some View {       COMMENT - Generate View       COMMENT - Use data from 'entry' to fill widget   }       struct ThisWeekWidget: Widget {     let kind: String = K.thisWeekWidget         var body: some WidgetConfiguration {       StaticConfiguration(kind: kind, provider: ThisWeekProvider()) { entry in         ThisWeekWidgetEntryView(entry: entry)       }       .configurationDisplayName("this_week_widget".localized())       .description("this_week_description".localized())       .supportedFamilies([.systemSmall])     }   } The custom data type 'TimeSummaryJSON' is as follows:   struct TimeSummaryJSON: Codable {           var labourIncome: String = "$0.00"     var equipmentIncome: String = "$0.00"     var days: String = "0"     var hours: String = "0"           var endDate: Date = Date()     var settingsFirstDayOfWeek: String = K.monday     var localeFirstDayOfWeek: Bool = false         } The custom function that retrieves the data 'getThisWeekData()' is as follows:   private func getThisWeekData() - TimeSummaryJSON {     if let encodedData = UserDefaults(suiteName: AppGroup.shared.rawValue)!.object(forKey: K.thisWeek) as? Data {       if let thisWeekJSON = try? JSONDecoder().decode(TimeSummaryJSON.self, from: encodedData) {         return checkExpiryForCurrentWeek(thisWeekJSON)       } else {         print("Decoding Error - Return Default This Week")         return getDefaultTimeSummaryJSON()       }     } else {       print("No Shared Data - Return Default This Week")       return getDefaultTimeSummaryJSON()     }   } The process of saving and retrieving the data works like this: SceneDelegate calls sceneWillResignActive Data is pulled from the Local Realm Database, calculated and saved into a TimeSummaryJSON TimeSummaryJSON is encoded and saved to a shared AppGroup WidgetCenter.shared calls reloadAllTimelines() Widget decodes JSON data from AppGroup If the JSON Decode is successful the current user data is shown in the widget, if the JSON Decode fails a default TimeSummaryJSON is sent instead I've looked over my code quite extensively and read countless forums and it seems that I am doing everything correctly. Have I missed something? Could anyone suggest why the behaviour is inconsistent between devices? I'm well and truly stuck and am not sure what to try next. Any help you can offer would be kindly appreciated. Thank you!
2
0
2.1k
Apr ’21