iOS is the operating system for iPhone.

All subtopics
Posts under iOS topic

Post

Replies

Boosts

Views

Activity

VoiceOver Headings Accessibility Rotor with SwiftUI on iOS
Hi, On iOS, I'd like to mark views that are inside a LazyVStack as headers for VoiceOver (make them appear in the headings rotor). In a VStack, you just have add .accessibilityAddTraits(.isHeader) to your header view. However, if your view is in a LazyVStack, that won't work if the view is not visible. As its name implies, LazyVStack is lazy so that makes sense. There is very little information online about system rotors, but it seems you are supposed to use .accessibilityRotor() with the headings system rotor (.accessibilityRotor(.headings)) outside of the LazyVStack. Something like the following. .accessibilityRotor(.headings) { ForEach(entries) { entry in // entry.id must be the same as the id of the SwiftUI view it is about AccessibilityRotorEntry(entry.name, id: entry.id) } } It kinds of work, but only kind of. When using .accessibilityAddTraits(.isHeader) in a VStack, the view is in the headings rotor as soon as you change screen. However, when using .accessibilityRotor(.headings), the headers (headings?) are not in the headings rotor at the time the screen appears. You have to move the accessibility focus inside the screen before your headers show up. I'm a beginner in regards to VoiceOver, so I don't know how a blind user used to VoiceOver would perceive this, but it feels to me that having to move the focus before the headers are in the headings rotor would mean some users would miss them. So my question is: is there a way to have headers inside a LazyVStack (and are not necessarily visible at first) to be in the headings rotor as soon as the screen appears? (be it using .accessibilityRotor(.headings) or anything else) The "SwiftUI Accessibility: Beyond the basics" talk from WWDC 2021 mentions custom rotors, not system rotors, but that should be close enough. It mentions that for accessibilityRotor to work properly it has to be applied on an accessibility container, so just in case I tried to move my .accessibilityRotor(.headings) to multiple places, with and without the accessibilityElement(children: .contain) modifier, but that did not seem to change the behavior (and I could not understand why accessibilityRotor could not automatically make the view it is applied on an accessibility container if needed). Also, a related question: when using .accessibilityRotor(.headings) on a screen, is it fine to mix uses of .accessibilityRotor(.headings) and .accessibilityRotor(.headings)? In a screen with multiple type of contents (something like ScrollView { VStack { MyHeader(); LazyVStack { /* some content */ }; LazyVStack { /* something else */ } } }), having to declare all headers in one place would make code reusability harder. Thanks
0
0
113
Jun ’25
IOS 26 Beta, Unexpected Liquid Navigation Bar Blured the whole View
I use .scaleEffect(x: 1, y: -1, anchor: .center) to reverse the messages list, so that the latest message always at the bottom. This is correct in ios18, but blurred the whole view in ios26. Complete code: ScrollView { Rectangle() .fill(.clear) .frame(height: 10) // if messages.isEmpty { // MessagesEmpty() // .padding(.horizontal, 10) // .scaleEffect(x: 1, y: -1, anchor: .center) // } MessageInput(chat: chat) .padding(.horizontal, 10) .scaleEffect(x: 1, y: -1, anchor: .center).id("#messag-input-identifier") LazyVStack(spacing: 10) { ForEach(messages) { (message: Message) in MessageItem(message: message, activation: $activeMessageId, audioAdapter: AudioAdapter.shared).id(message.id) } .padding(.horizontal, 10) .scaleEffect(x: 1, y: -1, anchor: .center) } Rectangle() .fill(.clear) .frame(height: 20) } .scaleEffect(x: 1, y: -1, anchor: .center) As shown in the screenshot WechatIMG49.jpg(using ios26beta which is incorrect), WechatIMG50.jpg(using ios18 which is correct) my messages list displays normally on iOS 18, but when using iOS 26 Beta, the entire view is blurred. IOS 26 Beta(Error): IOS 18(Correct):
Topic: UI Frameworks SubTopic: SwiftUI Tags:
1
0
309
Oct ’25
Video on Safari iOS - UI/UX of Shadow Content User Agent
Hi, when I display an HTML page with a on Safari iOS, I get a nice UI. Great! At the first look I see a video frame with an arrow-in-a-circle button in the middle. Very nice. I click on the arrow and I get a fullscreen view while the video begins to play. I watch the video then I pause it then I click on the top-left x button. So I go back to my html page and the video is perfectly there as it was before. But, there is an annoying new detail. The video frame is really dark, it still presents all the controls and a "different" arrow button to play it again. In other words that nice video-frame, that nice picture, is not longer visible on the page. That nice page with nice pictures has now an almost-black rectangle. Too bad. Sure I can click on the video (outside the controls) then the controls and the black overlaying frame disappear. I can see that nice picture again. Finally. Well, but the arrow-in-a-circle button to play the video disappeared. Now the user cannot longer understand that's a video to play. It looks just like any other pictures to admire statically. Is any way to get the previous first look of the video? The one clear, with the current frame and the arrow-in-a-circle look?
0
0
223
Apr ’25
SwiftUI List scroll indicator stutters, does not call `onAppear` or `onDisappear` consistently in iOS 16
My team has been debugging problems with the SwiftUI List component this week. We have found that it's performance is sub-optimal on iOS 16. You can see a simple grid of images, the scroll indicator stutters when scrolling down: Now compare it to what happens when we use a ScrollView with a LazyVStack: (An error occurred while uploading my second image, but pretend you see a scroll indicator moving smoothly down the side of the screen). You can see the scroll indicator moves smoothly without issue. We also found that the ScrollView combined with a LazyVStack properly calls onDisappear, which enables us to call a cancel method on the async image loading code that we use for our individual cells in this example. Though in a previous question, it was asserted that onDisappear cannot be reliably expected to be called in a List, I do not feel that answer is correct or proper behavior. Is this a bug, or is this expected behavior on a List? This is the cell that is being rendered: struct UserGridCell: View {   let stackId: String   let user: ProfileGridCellUIModel   let userGridCellType: UserGridCellType   @State var labelFrame: CGRect = .zero       private var isOnlineAcessibilityValue: String {     return user.isOnline == true ? "" : ""   }       init(stackId: String,      user: ProfileGridCellUIModel,      userGridCellType: UserGridCellType   ) {           self.stackId = stackId     self.user = user     self.userGridCellType = userGridCellType   }   var body: some View {     GeometryReader { containerGeometry in       ZStack(alignment: .bottom) {         HStack(spacing: 4) {                       let statusAccentColor: Color = .red                                   Circle()             .frame(width: 8, height: 8)             .foregroundColor(statusAccentColor)                       Text(String(user.remoteId) ?? "")             .lineLimit(1)             .foregroundColor(.black)             .overlay(GeometryReader { textGeometry in               Text("").onAppear {                 self.labelFrame = textGeometry.frame(in: .global)               }             })         }         .frame(maxWidth: .infinity, alignment: .bottomLeading)         .padding(.leading, 8)         .padding(.trailing, 8)         .padding(.bottom, 8)       }       .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)       .contentShape(Rectangle())       .accessibilityLabel(Text(user.name ?? ""))       .accessibilityValue(isOnlineAcessibilityValue)     }     .background(       ZStack {         AsyncProfileImage(request: URLRequest(url: URL(string: "https://picsum.photos/id/\(100 + user.remoteId)/200/300")!))       }         .accessibilityHidden(true)     )     .overlay(       RoundedRectangle(cornerRadius: 4)         .stroke(.red, lineWidth: user.hasAnyUnreadMessages ? 4 : 0)     )     .cornerRadius(4)   } } This is the code that renders each cell: struct ProfileGrid: View {   public static var AspectRatio: CGFloat = 0.75   @Environment(\.horizontalSizeClass) var horizontalSizeClass   @Environment(\.redactionReasons) private var reasons   private let stacks: [ProfileGridStackUIModel]   public init(stacks: [ProfileGridStackUIModel]   ) {     self.stacks = stacks   }       var body: some View {     let columnCount: Int = 3           // If you use a list, you will get the stutter. If you use what you see below, // it will render properly.     ScrollView {       LazyVStack {         ForEach(stacks, id: \.self) { stack in           Grid(stack: stack, columns: columnCount)         }       }     }     .buttonStyle(PlainButtonStyle())     .listStyle(PlainListStyle())   }       @ViewBuilder private func Grid(stack: ProfileGridStackUIModel, columns: Int) -> some View {     let chunks = stride(from: 0, to: stack.profiles.count, by: columns).map {       Array(stack.profiles[$0..<min($0 + columns, stack.profiles.count)])     }                   ForEach(chunks, id: \.self) { chunk in       GridRow(chunk: chunk, stack: stack, columns: columns)         .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))     }   }       @ViewBuilder private func GridRow(chunk: [ProfileGridCellUIModel], stack: ProfileGridStackUIModel, columns: Int) -> some View {     let emptyElements = columns - chunk.count     HStack(spacing: 8) {       ForEach(chunk) { user in         UserGridCell(stackId: "id",                user: user,                userGridCellType: .grid)         .aspectRatio(ProfileGrid.AspectRatio, contentMode: .fill)       }               if emptyElements > 0 {         ForEach(0..<emptyElements, id: \.self) { _ in           Rectangle()             .foregroundColor(Color.clear)             .contentShape(Rectangle())             .frame(maxWidth: .infinity)             .aspectRatio(ProfileGrid.AspectRatio, contentMode: .fill)         }       }     }   } }
2
0
2.2k
Jul ’25
UITabBarController bottom accessory doesn't resize properly when horizontal size class changes from compact to regular
A bottom accessory view is set on the UITabBarController. When changing the window size either by dragging the resizing grip or when going to portrait mode, the accessory view shrinks down to the smaller width. When resizing the window to make it larger, the accessory view doesn’t resize to the full available width. During a workshop setup by Apple, folks from Apple told me that the view set as the content view of the UITabAccessory should not have its frame changed, either by using Auto Layout or by setting the frame. It seems logical since the view in the bottom accessory is supposed to resize accordingly to several factors, like when going inline inside the tab bar. Am I missing something? Maybe there is additional setup required not mentioned in the dedicated video. Feedback is FB19017330. It contains a sample project and videos demonstrating the issue. Reproduced on Xcode 26 beta 6 (17A5305f) I copy and paste the sample code that setups the bottom accessory for good measure. final class MiniPlayer: UIView { let label = UILabel() override init(frame: CGRect) { super.init(frame: frame) label.text = "Mini Player" label.numberOfLines = 0 label.textAlignment = .center addSubview(label) label.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ label.centerXAnchor.constraint(equalTo: centerXAnchor), label.centerYAnchor.constraint(equalTo: centerYAnchor) ]) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } // MARK: - View Controller class ViewController: UIViewController { let rootTabBarController = UITabBarController() let miniPlayer = MiniPlayer() override func viewDidLoad() { super.viewDidLoad() let items: [UITab] = [ UITab(title: "Tab 1", image: UIImage(systemName: "archivebox.fill"), identifier: "tab-1") { _ in UIViewController() }, UITab(title: "Tab 2", image: UIImage(systemName: "books.vertical.fill"), identifier: "tab-2") { _ in UIViewController() }, UISearchTab { _ in UIViewController() } ] rootTabBarController.tabs = items rootTabBarController.view.backgroundColor = .secondarySystemBackground view.addSubview(rootTabBarController.view) rootTabBarController.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ rootTabBarController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), rootTabBarController.view.topAnchor.constraint(equalTo: view.topAnchor), rootTabBarController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), rootTabBarController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) rootTabBarController.bottomAccessory = UITabAccessory(contentView: miniPlayer) } }
0
0
234
Aug ’25
App Rejection Guideline 2.1 - Performance - App Completeness
I have been appealing to Apple to delete this rejected build since we have a new API and an upgraded new build with new IOS version to submit but we must up a version from 2 to 3. But the review BOT, I believe, doesn't read my appeal. It keeps responding with exactly the same rejection notes as before. I don't see the [+] button top left so I can't add a new version. I sent emails and made appeals to the "Review Board" link and submitted a case. There has been no response. It's been over a month. Can anyone recommend a solution, please?
1
0
117
Jun ’25
iOS26 beta ToolbarItem with placement to principal width is not fill to screen
I’m trying to add a TextField to the toolbar using .principal placement, and I want it to either fill the screen width or expand based on the surrounding content. However, it’s not resizing as expected — the TextField only resizes correctly when I provide a hardcoded width value. This behavior was working fine in previous versions of Xcode, but seems to be broken in Xcode 26. Not sure if this is an intentional change or a bug. i am using iOS26 beta and Xcode 26 beta struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() .toolbar { ToolbarItem(placement: .principal) { HStack { TextField("Search", text: .constant("")) .textFieldStyle(.roundedBorder) .frame(maxWidth: .infinity) // .frame(width: 300) Button("cancel") { } } .frame(maxWidth: .infinity) } } } } #Preview { NavigationView { ContentView() } }
0
0
279
Jun ’25
Microphone is not being detected in Safari on iOS
What I am trying to do is very simple. Environment description: macOS Catalina version 10.15.7 iOS Simulator version 12.3 Target device iPhone 11 (iOS 13.2.2) Open Safari > go to website > mictests.com Result: "Could not find any media devices. It is very likely that your browser does not allow access to these devices." The Simulator does have access to the microphone. I can use Siri just fine. Only Safari cannot access the mic. I'm really stuck here, any ideas are welcome.
1
0
934
Sep ’25
NSTextLists not rendered when NSTextContentStorageDelegate textContentStorage (_:, textParagraphWith:) is implemented
I have a UITextView that contains paragraphs with text bullet lists (via NSTextList). I also implement NSTextContentStorageDelegate.textContentStorage(_:, textParagraphWith:) in order to apply some custom attributes to the text without affecting the underlying attributed text. My implementation returns a new NSParagraph that modifies the foreground color of the text. I based this on the example in the WWDC 21 session "Meet Text Kit 2". UITextView stops rendering the bullets when I implement the delegate function and return a custom paragraph. Why? func textContentStorage(_ textContentStorage: NSTextContentStorage, textParagraphWith range: NSRange) -> NSTextParagraph? { guard let originalText = textContentStorage.textStorage?.attributedSubstring(from: range) else { return nil } let updatedText = NSMutableAttributedString(attributedString: originalText) updatedText.addAttribute(.foregroundColor, value: UIColor.green, range: NSRange(location: 0, length: updatedText.length)) let paragraph = NSTextParagraph(attributedString: updatedText) // Verify that the text still contains NSTextList if let paragraphStyle = paragraph.attributedString.attribute(.paragraphStyle, at: 0, effectiveRange: nil) as? NSParagraphStyle { assert(!paragraphStyle.textLists.isEmpty) } else { assertionFailure("Paragraph has lost its text lists") } return paragraph }
0
0
360
May ’25
UIDocumentPickerViewController dismisses presenting view controller when selecting a file multiple times quickly
Description When using UIDocumentPickerViewController with allowsMultipleSelection = false, I expect that selecting a file will dismiss only the document picker. However, if a user quickly taps the same file multiple times, the picker dismisses both itself and the presenting view controller (i.e., it pops two levels from the view controller stack), which leads to unintended behavior and breaks presentation flow. Expected Behavior Only UIDocumentPickerViewController should be dismissed when a file is selected—even if the user taps quickly or multiple times on the same file. Actual Behavior When tapping the same file multiple times quickly, the picker dismisses not only itself but also the parent view controller it was presented from. Steps to Reproduce Create a simple view controller and present another one modally over it. From that presented view controller, present a UIDocumentPickerViewController with allowsMultipleSelection = false. Tap quickly on the same file in the picker 2 times. Result: Both the document picker and the presenting view controller are dismissed. Reproducible Code Snippet class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .green addLabel("Parent View Controller") DispatchQueue.main.async { [unowned self] in let child = UIViewController() child.view.backgroundColor = .yellow present(child, animated: true) child.addLabel("Child View Controller") let vc = UIDocumentPickerViewController( forOpeningContentTypes: [.pdf, .jpeg, .png], asCopy: true ) vc.allowsMultipleSelection = false child.present(vc, animated: true) } } } extension UIViewController { func addLabel(_ text: String) { let label = UILabel(frame: CGRect(x: 0, y: 50, width: view.bounds.width, height: 30)) label.text = text view.addSubview(label) } } Environment Device: iPhone 15 Pro and others iOS version: 18.2 (reproduces on multiple iOS versions) Occurs with: .pdf, .jpeg, .png file types Mode: Both simulator and real device Notes Happens consistently with fast multiple taps on the same file. This breaks expected view controller stack behavior.
0
0
144
Apr ’25
File Provider Extension Sandbox Prevents Shared Library from having write access to temporary storage or App Group.
I'm not sure if I have found a bug with iOS or if it's just unexpected behavior with my implementation. I have a gomobile library that sets up a local http server. It needs to be able to write to temporary storage. If I use the shared library from my main apps process it can write to the file manager.default temporary storage. while Xcode is running a debug session I can use that same process from my file provider replicated extension and it works fine. However I realized running my file provider extension where it starts the gomobile shared library directly instead of first from my app the library fails to write anything to the file provider manager default temporary storage or the file provider manager for my file provider domain temporary storage or even the app group library. it is odd, because I have a swift URL extension that confirms the temporary storage can be written to from swift. I have monitored console logs for fileproviderd, my file extension and have tried writing data to a log file. nothing seems to catch exactly what causes the file provider extension to crash and restart. I also cannot keep the shared gomobile server running in the background on iOS even if I were to force the user to "authenticate" with the main app first. Im pretty sure the file provider extension needs to run the gomobile library for it to work right. I'm wondering if something may be wrong with the iOS sandbox that could be preventing the file provider extension to let a c based gomobile shared library from accessing the temporary storage. Any guidance for further things to try would be greatly appreciated. I have tried every avenue I can think of. I cannot run just the appex itself on either my m4 pro MacBook or my iPhone so attaching the debugger has been tricky and I don't see much in the way of useful logs in console app either just a swarm of noise. Im fairly confident it's an issue to writing to temporary storage from the gomobile c library and not much else. App was working great on macOS designed for iPad which just seemed rather ironic that an iOS code base runs better on macOS than it was able to on my iPhone 16 pro max. Like im all for the sandbox I just wish it didn't treat c level gomobile libraries different than it treats the swift code itself.
1
0
201
Jun ’25
How to achieve a pure backdrop blur effect without predefined tint color in SwiftUI / UIKit?
Hi everyone, I’m currently trying to create a pure backdrop blur effect in my iOS app (SwiftUI / UIKit), similar to the backdrop-filter: blur(20px) effect in CSS. My goal is simple: • Apply a Gaussian blur (radius ~20px) to the background content • Overlay a semi-transparent black layer (opacity 0.3) • Avoid any predefined color tint from UIBlurEffect or .ultraThinMaterial, etc. However, every method I’ve tried so far (e.g., .ultraThinMaterial, UIBlurEffect(style:)) always introduces a built-in tint, which makes the result look gray or washed out. Even when layering a black color with opacity 0.3 over .ultraThinMaterial, it doesn’t give the clean, transparent-black + blur look I want. What I’m looking for: • A clean 20px blur effect (like CIGaussianBlur) • No color shift/tint added by default • A layer of black at 30% opacity on top of the blur • Ideally works live (not a static snapshot blur) Has anyone achieved something like this in UIKit or SwiftUI? Would really appreciate any insights, workarounds, or libraries that can help. Thanks in advance! Ben
3
0
203
Jun ’25
Automatic App Icon Style Change in iOS 26
After updating from iOS 18 to iOS 26, our app icon appears to have automatically received the new 'Liquid Glass' effect. We confirmed that this change occurred without us releasing a new app update. My questions are: Is this a system behavior where iOS 26 automatically applies the new icon style to existing apps? If so, is it possible for a developer to control or customize this effect? I am also wondering if there are any methods other than using Icon Composer.
1
0
224
Aug ’25
Feedback on the new Camera app icon in iOS 26
I’m currently using the iOS 26 Developer Beta and noticed the new icon design for the Camera app. Personally, I preferred the previous icon it looked cleaner, more elegant, and felt more in line with Apple’s signature iOS design language. The new icon feels more like something you’d expect from Android. It lacks the minimalist, refined style that usually defines iOS icons. I understand UI evolves over time, but this change feels like a step away from what makes Apple’s design philosophy unique. Just wanted to share this honest feedback as a long-time user and developer. Thanks for considering!
Topic: Design SubTopic: General Tags:
2
0
205
Jun ’25
SKErrorDomain Code 2 Problem
We are facing a serious issues with in app purchases in our app. We offer 3 IAP: auto-renewable subscription 1W, auto-renewable subscription 1Y, non-consumable one-time purchase (LifeTime access) In our case 90-95% of transactions fail and we mostly get SKError code=2 . Sometime purchase fails several times for the same user so it’s very hard to believe that user intentionally cancels transaction for the same product 4 or even 5 times in a row. It happens regardless iOS version, device model, our app version. We've checked multiple threads with the same issue but coudn't find any solution. We do not offer any promotions, product identifiers are valid... Some users are able to make a purchases without any issues.
1
0
255
Jul ’25
Control Widget SF image cannot stably display
I'm working on the control widget which should display the SF image on the UI, but I have found that it cannot be displayed stably. I have three ExampleControlWidget which is about the type egA egB and egC, it should all be showed but now they only show the text and placeholder. I'm aware of the images should be SF image and I can see them to show perfectly sometimes, but in other time it is just failed. This's really confused me, can anyone help me out? public enum ControlWidgetType: Sendable { case egA case egB case egC public var imageName: String { switch self { case .egA: return "egA" case .egB: return "egB" case .egC: return "egC" } } } struct ExampleControlWidget: ControlWidget { var body: some ControlWidgetConfiguration { AppIntentControlConfiguration( kind: kind, provider: Provider() ) { example in ControlWidgetToggle( example.name, isOn: example.state.isOn, action: ExampleControlWidgetIntent(id: example.id), valueLabel: { isOn in ExampleControlWidgetView( statusText: isOn ? Localization.on.text : Localization.off.text, bundle: bundle, widgetType: .egA //or .egB .egC ) .symbolEffect(.pulse) } ) .disabled(example.state.isDisabled) } .promptsForUserConfiguration() } } public struct ExampleControlWidgetView: View { private let statusText: String private let bundle: Bundle private var widgetType: ControlWidgetType = .egA public init(statusText: String, bundle: Bundle, widgetType: ControlWidgetType) { self.statusText = statusText self.bundle = bundle self.widgetType = widgetType } public var body: some View { Label( statusText, image: .init( name: widgetType.imageName, // the SF Symbol image id bundled in the Widget extension bundle: bundle ) ) } } This is the normal display: These are the display that do not show properly: The results has no rules at all, I have tried to completely uninstall the APP and reinstall but the result is same.
3
0
387
Jan ’26
Delete me
Delete me
Replies
0
Boosts
0
Views
90
Activity
Jun ’25
VoiceOver Headings Accessibility Rotor with SwiftUI on iOS
Hi, On iOS, I'd like to mark views that are inside a LazyVStack as headers for VoiceOver (make them appear in the headings rotor). In a VStack, you just have add .accessibilityAddTraits(.isHeader) to your header view. However, if your view is in a LazyVStack, that won't work if the view is not visible. As its name implies, LazyVStack is lazy so that makes sense. There is very little information online about system rotors, but it seems you are supposed to use .accessibilityRotor() with the headings system rotor (.accessibilityRotor(.headings)) outside of the LazyVStack. Something like the following. .accessibilityRotor(.headings) { ForEach(entries) { entry in // entry.id must be the same as the id of the SwiftUI view it is about AccessibilityRotorEntry(entry.name, id: entry.id) } } It kinds of work, but only kind of. When using .accessibilityAddTraits(.isHeader) in a VStack, the view is in the headings rotor as soon as you change screen. However, when using .accessibilityRotor(.headings), the headers (headings?) are not in the headings rotor at the time the screen appears. You have to move the accessibility focus inside the screen before your headers show up. I'm a beginner in regards to VoiceOver, so I don't know how a blind user used to VoiceOver would perceive this, but it feels to me that having to move the focus before the headers are in the headings rotor would mean some users would miss them. So my question is: is there a way to have headers inside a LazyVStack (and are not necessarily visible at first) to be in the headings rotor as soon as the screen appears? (be it using .accessibilityRotor(.headings) or anything else) The "SwiftUI Accessibility: Beyond the basics" talk from WWDC 2021 mentions custom rotors, not system rotors, but that should be close enough. It mentions that for accessibilityRotor to work properly it has to be applied on an accessibility container, so just in case I tried to move my .accessibilityRotor(.headings) to multiple places, with and without the accessibilityElement(children: .contain) modifier, but that did not seem to change the behavior (and I could not understand why accessibilityRotor could not automatically make the view it is applied on an accessibility container if needed). Also, a related question: when using .accessibilityRotor(.headings) on a screen, is it fine to mix uses of .accessibilityRotor(.headings) and .accessibilityRotor(.headings)? In a screen with multiple type of contents (something like ScrollView { VStack { MyHeader(); LazyVStack { /* some content */ }; LazyVStack { /* something else */ } } }), having to declare all headers in one place would make code reusability harder. Thanks
Replies
0
Boosts
0
Views
113
Activity
Jun ’25
IOS 26 Beta, Unexpected Liquid Navigation Bar Blured the whole View
I use .scaleEffect(x: 1, y: -1, anchor: .center) to reverse the messages list, so that the latest message always at the bottom. This is correct in ios18, but blurred the whole view in ios26. Complete code: ScrollView { Rectangle() .fill(.clear) .frame(height: 10) // if messages.isEmpty { // MessagesEmpty() // .padding(.horizontal, 10) // .scaleEffect(x: 1, y: -1, anchor: .center) // } MessageInput(chat: chat) .padding(.horizontal, 10) .scaleEffect(x: 1, y: -1, anchor: .center).id("#messag-input-identifier") LazyVStack(spacing: 10) { ForEach(messages) { (message: Message) in MessageItem(message: message, activation: $activeMessageId, audioAdapter: AudioAdapter.shared).id(message.id) } .padding(.horizontal, 10) .scaleEffect(x: 1, y: -1, anchor: .center) } Rectangle() .fill(.clear) .frame(height: 20) } .scaleEffect(x: 1, y: -1, anchor: .center) As shown in the screenshot WechatIMG49.jpg(using ios26beta which is incorrect), WechatIMG50.jpg(using ios18 which is correct) my messages list displays normally on iOS 18, but when using iOS 26 Beta, the entire view is blurred. IOS 26 Beta(Error): IOS 18(Correct):
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
1
Boosts
0
Views
309
Activity
Oct ’25
Video on Safari iOS - UI/UX of Shadow Content User Agent
Hi, when I display an HTML page with a on Safari iOS, I get a nice UI. Great! At the first look I see a video frame with an arrow-in-a-circle button in the middle. Very nice. I click on the arrow and I get a fullscreen view while the video begins to play. I watch the video then I pause it then I click on the top-left x button. So I go back to my html page and the video is perfectly there as it was before. But, there is an annoying new detail. The video frame is really dark, it still presents all the controls and a "different" arrow button to play it again. In other words that nice video-frame, that nice picture, is not longer visible on the page. That nice page with nice pictures has now an almost-black rectangle. Too bad. Sure I can click on the video (outside the controls) then the controls and the black overlaying frame disappear. I can see that nice picture again. Finally. Well, but the arrow-in-a-circle button to play the video disappeared. Now the user cannot longer understand that's a video to play. It looks just like any other pictures to admire statically. Is any way to get the previous first look of the video? The one clear, with the current frame and the arrow-in-a-circle look?
Replies
0
Boosts
0
Views
223
Activity
Apr ’25
SwiftUI List scroll indicator stutters, does not call `onAppear` or `onDisappear` consistently in iOS 16
My team has been debugging problems with the SwiftUI List component this week. We have found that it's performance is sub-optimal on iOS 16. You can see a simple grid of images, the scroll indicator stutters when scrolling down: Now compare it to what happens when we use a ScrollView with a LazyVStack: (An error occurred while uploading my second image, but pretend you see a scroll indicator moving smoothly down the side of the screen). You can see the scroll indicator moves smoothly without issue. We also found that the ScrollView combined with a LazyVStack properly calls onDisappear, which enables us to call a cancel method on the async image loading code that we use for our individual cells in this example. Though in a previous question, it was asserted that onDisappear cannot be reliably expected to be called in a List, I do not feel that answer is correct or proper behavior. Is this a bug, or is this expected behavior on a List? This is the cell that is being rendered: struct UserGridCell: View {   let stackId: String   let user: ProfileGridCellUIModel   let userGridCellType: UserGridCellType   @State var labelFrame: CGRect = .zero       private var isOnlineAcessibilityValue: String {     return user.isOnline == true ? "" : ""   }       init(stackId: String,      user: ProfileGridCellUIModel,      userGridCellType: UserGridCellType   ) {           self.stackId = stackId     self.user = user     self.userGridCellType = userGridCellType   }   var body: some View {     GeometryReader { containerGeometry in       ZStack(alignment: .bottom) {         HStack(spacing: 4) {                       let statusAccentColor: Color = .red                                   Circle()             .frame(width: 8, height: 8)             .foregroundColor(statusAccentColor)                       Text(String(user.remoteId) ?? "")             .lineLimit(1)             .foregroundColor(.black)             .overlay(GeometryReader { textGeometry in               Text("").onAppear {                 self.labelFrame = textGeometry.frame(in: .global)               }             })         }         .frame(maxWidth: .infinity, alignment: .bottomLeading)         .padding(.leading, 8)         .padding(.trailing, 8)         .padding(.bottom, 8)       }       .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)       .contentShape(Rectangle())       .accessibilityLabel(Text(user.name ?? ""))       .accessibilityValue(isOnlineAcessibilityValue)     }     .background(       ZStack {         AsyncProfileImage(request: URLRequest(url: URL(string: "https://picsum.photos/id/\(100 + user.remoteId)/200/300")!))       }         .accessibilityHidden(true)     )     .overlay(       RoundedRectangle(cornerRadius: 4)         .stroke(.red, lineWidth: user.hasAnyUnreadMessages ? 4 : 0)     )     .cornerRadius(4)   } } This is the code that renders each cell: struct ProfileGrid: View {   public static var AspectRatio: CGFloat = 0.75   @Environment(\.horizontalSizeClass) var horizontalSizeClass   @Environment(\.redactionReasons) private var reasons   private let stacks: [ProfileGridStackUIModel]   public init(stacks: [ProfileGridStackUIModel]   ) {     self.stacks = stacks   }       var body: some View {     let columnCount: Int = 3           // If you use a list, you will get the stutter. If you use what you see below, // it will render properly.     ScrollView {       LazyVStack {         ForEach(stacks, id: \.self) { stack in           Grid(stack: stack, columns: columnCount)         }       }     }     .buttonStyle(PlainButtonStyle())     .listStyle(PlainListStyle())   }       @ViewBuilder private func Grid(stack: ProfileGridStackUIModel, columns: Int) -> some View {     let chunks = stride(from: 0, to: stack.profiles.count, by: columns).map {       Array(stack.profiles[$0..<min($0 + columns, stack.profiles.count)])     }                   ForEach(chunks, id: \.self) { chunk in       GridRow(chunk: chunk, stack: stack, columns: columns)         .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))     }   }       @ViewBuilder private func GridRow(chunk: [ProfileGridCellUIModel], stack: ProfileGridStackUIModel, columns: Int) -> some View {     let emptyElements = columns - chunk.count     HStack(spacing: 8) {       ForEach(chunk) { user in         UserGridCell(stackId: "id",                user: user,                userGridCellType: .grid)         .aspectRatio(ProfileGrid.AspectRatio, contentMode: .fill)       }               if emptyElements > 0 {         ForEach(0..<emptyElements, id: \.self) { _ in           Rectangle()             .foregroundColor(Color.clear)             .contentShape(Rectangle())             .frame(maxWidth: .infinity)             .aspectRatio(ProfileGrid.AspectRatio, contentMode: .fill)         }       }     }   } }
Replies
2
Boosts
0
Views
2.2k
Activity
Jul ’25
UITabBarController bottom accessory doesn't resize properly when horizontal size class changes from compact to regular
A bottom accessory view is set on the UITabBarController. When changing the window size either by dragging the resizing grip or when going to portrait mode, the accessory view shrinks down to the smaller width. When resizing the window to make it larger, the accessory view doesn’t resize to the full available width. During a workshop setup by Apple, folks from Apple told me that the view set as the content view of the UITabAccessory should not have its frame changed, either by using Auto Layout or by setting the frame. It seems logical since the view in the bottom accessory is supposed to resize accordingly to several factors, like when going inline inside the tab bar. Am I missing something? Maybe there is additional setup required not mentioned in the dedicated video. Feedback is FB19017330. It contains a sample project and videos demonstrating the issue. Reproduced on Xcode 26 beta 6 (17A5305f) I copy and paste the sample code that setups the bottom accessory for good measure. final class MiniPlayer: UIView { let label = UILabel() override init(frame: CGRect) { super.init(frame: frame) label.text = "Mini Player" label.numberOfLines = 0 label.textAlignment = .center addSubview(label) label.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ label.centerXAnchor.constraint(equalTo: centerXAnchor), label.centerYAnchor.constraint(equalTo: centerYAnchor) ]) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } // MARK: - View Controller class ViewController: UIViewController { let rootTabBarController = UITabBarController() let miniPlayer = MiniPlayer() override func viewDidLoad() { super.viewDidLoad() let items: [UITab] = [ UITab(title: "Tab 1", image: UIImage(systemName: "archivebox.fill"), identifier: "tab-1") { _ in UIViewController() }, UITab(title: "Tab 2", image: UIImage(systemName: "books.vertical.fill"), identifier: "tab-2") { _ in UIViewController() }, UISearchTab { _ in UIViewController() } ] rootTabBarController.tabs = items rootTabBarController.view.backgroundColor = .secondarySystemBackground view.addSubview(rootTabBarController.view) rootTabBarController.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ rootTabBarController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), rootTabBarController.view.topAnchor.constraint(equalTo: view.topAnchor), rootTabBarController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), rootTabBarController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) rootTabBarController.bottomAccessory = UITabAccessory(contentView: miniPlayer) } }
Replies
0
Boosts
0
Views
234
Activity
Aug ’25
App Rejection Guideline 2.1 - Performance - App Completeness
I have been appealing to Apple to delete this rejected build since we have a new API and an upgraded new build with new IOS version to submit but we must up a version from 2 to 3. But the review BOT, I believe, doesn't read my appeal. It keeps responding with exactly the same rejection notes as before. I don't see the [+] button top left so I can't add a new version. I sent emails and made appeals to the "Review Board" link and submitted a case. There has been no response. It's been over a month. Can anyone recommend a solution, please?
Replies
1
Boosts
0
Views
117
Activity
Jun ’25
iOS26 beta ToolbarItem with placement to principal width is not fill to screen
I’m trying to add a TextField to the toolbar using .principal placement, and I want it to either fill the screen width or expand based on the surrounding content. However, it’s not resizing as expected — the TextField only resizes correctly when I provide a hardcoded width value. This behavior was working fine in previous versions of Xcode, but seems to be broken in Xcode 26. Not sure if this is an intentional change or a bug. i am using iOS26 beta and Xcode 26 beta struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() .toolbar { ToolbarItem(placement: .principal) { HStack { TextField("Search", text: .constant("")) .textFieldStyle(.roundedBorder) .frame(maxWidth: .infinity) // .frame(width: 300) Button("cancel") { } } .frame(maxWidth: .infinity) } } } } #Preview { NavigationView { ContentView() } }
Replies
0
Boosts
0
Views
279
Activity
Jun ’25
Microphone is not being detected in Safari on iOS
What I am trying to do is very simple. Environment description: macOS Catalina version 10.15.7 iOS Simulator version 12.3 Target device iPhone 11 (iOS 13.2.2) Open Safari > go to website > mictests.com Result: "Could not find any media devices. It is very likely that your browser does not allow access to these devices." The Simulator does have access to the microphone. I can use Siri just fine. Only Safari cannot access the mic. I'm really stuck here, any ideas are welcome.
Replies
1
Boosts
0
Views
934
Activity
Sep ’25
NSTextLists not rendered when NSTextContentStorageDelegate textContentStorage (_:, textParagraphWith:) is implemented
I have a UITextView that contains paragraphs with text bullet lists (via NSTextList). I also implement NSTextContentStorageDelegate.textContentStorage(_:, textParagraphWith:) in order to apply some custom attributes to the text without affecting the underlying attributed text. My implementation returns a new NSParagraph that modifies the foreground color of the text. I based this on the example in the WWDC 21 session "Meet Text Kit 2". UITextView stops rendering the bullets when I implement the delegate function and return a custom paragraph. Why? func textContentStorage(_ textContentStorage: NSTextContentStorage, textParagraphWith range: NSRange) -> NSTextParagraph? { guard let originalText = textContentStorage.textStorage?.attributedSubstring(from: range) else { return nil } let updatedText = NSMutableAttributedString(attributedString: originalText) updatedText.addAttribute(.foregroundColor, value: UIColor.green, range: NSRange(location: 0, length: updatedText.length)) let paragraph = NSTextParagraph(attributedString: updatedText) // Verify that the text still contains NSTextList if let paragraphStyle = paragraph.attributedString.attribute(.paragraphStyle, at: 0, effectiveRange: nil) as? NSParagraphStyle { assert(!paragraphStyle.textLists.isEmpty) } else { assertionFailure("Paragraph has lost its text lists") } return paragraph }
Replies
0
Boosts
0
Views
360
Activity
May ’25
UIDocumentPickerViewController dismisses presenting view controller when selecting a file multiple times quickly
Description When using UIDocumentPickerViewController with allowsMultipleSelection = false, I expect that selecting a file will dismiss only the document picker. However, if a user quickly taps the same file multiple times, the picker dismisses both itself and the presenting view controller (i.e., it pops two levels from the view controller stack), which leads to unintended behavior and breaks presentation flow. Expected Behavior Only UIDocumentPickerViewController should be dismissed when a file is selected—even if the user taps quickly or multiple times on the same file. Actual Behavior When tapping the same file multiple times quickly, the picker dismisses not only itself but also the parent view controller it was presented from. Steps to Reproduce Create a simple view controller and present another one modally over it. From that presented view controller, present a UIDocumentPickerViewController with allowsMultipleSelection = false. Tap quickly on the same file in the picker 2 times. Result: Both the document picker and the presenting view controller are dismissed. Reproducible Code Snippet class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .green addLabel("Parent View Controller") DispatchQueue.main.async { [unowned self] in let child = UIViewController() child.view.backgroundColor = .yellow present(child, animated: true) child.addLabel("Child View Controller") let vc = UIDocumentPickerViewController( forOpeningContentTypes: [.pdf, .jpeg, .png], asCopy: true ) vc.allowsMultipleSelection = false child.present(vc, animated: true) } } } extension UIViewController { func addLabel(_ text: String) { let label = UILabel(frame: CGRect(x: 0, y: 50, width: view.bounds.width, height: 30)) label.text = text view.addSubview(label) } } Environment Device: iPhone 15 Pro and others iOS version: 18.2 (reproduces on multiple iOS versions) Occurs with: .pdf, .jpeg, .png file types Mode: Both simulator and real device Notes Happens consistently with fast multiple taps on the same file. This breaks expected view controller stack behavior.
Replies
0
Boosts
0
Views
144
Activity
Apr ’25
File Provider Extension Sandbox Prevents Shared Library from having write access to temporary storage or App Group.
I'm not sure if I have found a bug with iOS or if it's just unexpected behavior with my implementation. I have a gomobile library that sets up a local http server. It needs to be able to write to temporary storage. If I use the shared library from my main apps process it can write to the file manager.default temporary storage. while Xcode is running a debug session I can use that same process from my file provider replicated extension and it works fine. However I realized running my file provider extension where it starts the gomobile shared library directly instead of first from my app the library fails to write anything to the file provider manager default temporary storage or the file provider manager for my file provider domain temporary storage or even the app group library. it is odd, because I have a swift URL extension that confirms the temporary storage can be written to from swift. I have monitored console logs for fileproviderd, my file extension and have tried writing data to a log file. nothing seems to catch exactly what causes the file provider extension to crash and restart. I also cannot keep the shared gomobile server running in the background on iOS even if I were to force the user to "authenticate" with the main app first. Im pretty sure the file provider extension needs to run the gomobile library for it to work right. I'm wondering if something may be wrong with the iOS sandbox that could be preventing the file provider extension to let a c based gomobile shared library from accessing the temporary storage. Any guidance for further things to try would be greatly appreciated. I have tried every avenue I can think of. I cannot run just the appex itself on either my m4 pro MacBook or my iPhone so attaching the debugger has been tricky and I don't see much in the way of useful logs in console app either just a swarm of noise. Im fairly confident it's an issue to writing to temporary storage from the gomobile c library and not much else. App was working great on macOS designed for iPad which just seemed rather ironic that an iOS code base runs better on macOS than it was able to on my iPhone 16 pro max. Like im all for the sandbox I just wish it didn't treat c level gomobile libraries different than it treats the swift code itself.
Replies
1
Boosts
0
Views
201
Activity
Jun ’25
New iOS 26 Beta Xcode Support for Older Version of Xcode
I have an older Macbook, and it only supports Xcode 15.2, and I want to be able to work with my iPhone SE 3rd gen, which currently has the iOS 26 beta on it. Is there a place I can find the download for that, and can I even run it on that version of Xcode? If not, can I download a newer version of Xcode on MacOS Ventura?
Replies
2
Boosts
0
Views
342
Activity
Jun ’25
How to achieve a pure backdrop blur effect without predefined tint color in SwiftUI / UIKit?
Hi everyone, I’m currently trying to create a pure backdrop blur effect in my iOS app (SwiftUI / UIKit), similar to the backdrop-filter: blur(20px) effect in CSS. My goal is simple: • Apply a Gaussian blur (radius ~20px) to the background content • Overlay a semi-transparent black layer (opacity 0.3) • Avoid any predefined color tint from UIBlurEffect or .ultraThinMaterial, etc. However, every method I’ve tried so far (e.g., .ultraThinMaterial, UIBlurEffect(style:)) always introduces a built-in tint, which makes the result look gray or washed out. Even when layering a black color with opacity 0.3 over .ultraThinMaterial, it doesn’t give the clean, transparent-black + blur look I want. What I’m looking for: • A clean 20px blur effect (like CIGaussianBlur) • No color shift/tint added by default • A layer of black at 30% opacity on top of the blur • Ideally works live (not a static snapshot blur) Has anyone achieved something like this in UIKit or SwiftUI? Would really appreciate any insights, workarounds, or libraries that can help. Thanks in advance! Ben
Replies
3
Boosts
0
Views
203
Activity
Jun ’25
Automatic App Icon Style Change in iOS 26
After updating from iOS 18 to iOS 26, our app icon appears to have automatically received the new 'Liquid Glass' effect. We confirmed that this change occurred without us releasing a new app update. My questions are: Is this a system behavior where iOS 26 automatically applies the new icon style to existing apps? If so, is it possible for a developer to control or customize this effect? I am also wondering if there are any methods other than using Icon Composer.
Replies
1
Boosts
0
Views
224
Activity
Aug ’25
Testflight of Finnia
Hello there! I have developed a website (https://finnia.ch). Now I have transformed it to an app (with webview). If anyone would like to check it out and test it here is the link: https://testflight.apple.com/join/hmyDw74t It is a administration tool (not a game). Simon
Replies
0
Boosts
0
Views
110
Activity
Jun ’25
Feedback on the new Camera app icon in iOS 26
I’m currently using the iOS 26 Developer Beta and noticed the new icon design for the Camera app. Personally, I preferred the previous icon it looked cleaner, more elegant, and felt more in line with Apple’s signature iOS design language. The new icon feels more like something you’d expect from Android. It lacks the minimalist, refined style that usually defines iOS icons. I understand UI evolves over time, but this change feels like a step away from what makes Apple’s design philosophy unique. Just wanted to share this honest feedback as a long-time user and developer. Thanks for considering!
Topic: Design SubTopic: General Tags:
Replies
2
Boosts
0
Views
205
Activity
Jun ’25
XCode15&XCode16获取屏幕宽高不同
iPhone16ProMax 通过[UIScreen mainScreen].bounds.size获取屏幕宽高 使用XCode15获取屏幕宽高为430 * 930 使用XCode16获取屏幕宽高为440 * 956 这是为什么?
Replies
0
Boosts
0
Views
106
Activity
May ’25
SKErrorDomain Code 2 Problem
We are facing a serious issues with in app purchases in our app. We offer 3 IAP: auto-renewable subscription 1W, auto-renewable subscription 1Y, non-consumable one-time purchase (LifeTime access) In our case 90-95% of transactions fail and we mostly get SKError code=2 . Sometime purchase fails several times for the same user so it’s very hard to believe that user intentionally cancels transaction for the same product 4 or even 5 times in a row. It happens regardless iOS version, device model, our app version. We've checked multiple threads with the same issue but coudn't find any solution. We do not offer any promotions, product identifiers are valid... Some users are able to make a purchases without any issues.
Replies
1
Boosts
0
Views
255
Activity
Jul ’25
Control Widget SF image cannot stably display
I'm working on the control widget which should display the SF image on the UI, but I have found that it cannot be displayed stably. I have three ExampleControlWidget which is about the type egA egB and egC, it should all be showed but now they only show the text and placeholder. I'm aware of the images should be SF image and I can see them to show perfectly sometimes, but in other time it is just failed. This's really confused me, can anyone help me out? public enum ControlWidgetType: Sendable { case egA case egB case egC public var imageName: String { switch self { case .egA: return "egA" case .egB: return "egB" case .egC: return "egC" } } } struct ExampleControlWidget: ControlWidget { var body: some ControlWidgetConfiguration { AppIntentControlConfiguration( kind: kind, provider: Provider() ) { example in ControlWidgetToggle( example.name, isOn: example.state.isOn, action: ExampleControlWidgetIntent(id: example.id), valueLabel: { isOn in ExampleControlWidgetView( statusText: isOn ? Localization.on.text : Localization.off.text, bundle: bundle, widgetType: .egA //or .egB .egC ) .symbolEffect(.pulse) } ) .disabled(example.state.isDisabled) } .promptsForUserConfiguration() } } public struct ExampleControlWidgetView: View { private let statusText: String private let bundle: Bundle private var widgetType: ControlWidgetType = .egA public init(statusText: String, bundle: Bundle, widgetType: ControlWidgetType) { self.statusText = statusText self.bundle = bundle self.widgetType = widgetType } public var body: some View { Label( statusText, image: .init( name: widgetType.imageName, // the SF Symbol image id bundled in the Widget extension bundle: bundle ) ) } } This is the normal display: These are the display that do not show properly: The results has no rules at all, I have tried to completely uninstall the APP and reinstall but the result is same.
Replies
3
Boosts
0
Views
387
Activity
Jan ’26