Hi Team,
its been observed that, there are some Spam calls which triggers the face recognitions and disappear within few seconds, what i mean is that while you see at screen who is calling the facial recognition scans your face… i had this episodes many times..
Posts under iOS tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Is the Cancel button intentionally removed from UISearchBar (right side)?
Even when using searchController with navigationItem also.
showsCancelButton = true
doesn’t display the cancel button.
Also:
When tapping the clear ("x") button inside the search field, the search is getting canceled, and searchBarCancelButtonClicked(_:) is triggered (Generally it should only clear text, not cancel search).
If the search text is empty and I tap outside the search bar, the search is canceled.
Also when I have tableview in my controller(like recent searches) below search bar and if I try to tap when editing started, action is not triggered(verified in sample too). Just cancellation is happening.
In a split view controller, if the search is on the right side and I try to open the side panel, the search also gets canceled.
Are these behaviors intentional changes, beta issues, or are we missing something in implementation?
Starting from iOS 26 simulator (beta 7), I could not see any debugDescription from UIToolbar. The Accessibility Inspector tool could not see anything beneath the toolbar even if we can see elements like static texts and buttons on the simulator.
When the same app is run on an iOS 18.2 simulator, the debugDescription for elements under a UIToolbar is available.
Is the absence of debugDescription for UIToolbar a bug?
Hello!
The minimize behavior was working correctly while I was using Xcode 26 beta 4 with iOS 26 beta 4 simulator — when scrolling down, the Tab Bar would minimize as expected.
However, after upgrading both Xcode and iOS simulator to beta 5, the tabBarMinimizeBehavior setting no longer has any visible effect — the Tab Bar stays fixed in place.
Code snippet:
if #available(iOS 26.0, *) {
self.tabBarMinimizeBehavior = .onScrollDown
}
Steps to reproduce:
1. Create a UITabBarController with at least one tab containing a scrollable view (e.g., UITableView).
2. In viewDidLoad, set tabBarMinimizeBehavior to .onScrollDown.
3. Run on iOS 26 beta 5 simulator.
Expected behavior (beta 4):
Scrolling down hides/minimizes the Tab Bar with animation.
Actual behavior (beta 5):
Tab Bar remains fixed; no minimize animation is triggered.
Environment:
• Xcode 26 beta 5 (Build: 17A5295f)
• iOS 26 beta 5 simulator (Build: 1055) – iPhone 16 Pro
• Also tested on iPhone 13 mini – iOS 26 (Build: 23A5308g)
Hello All,
I am currently developing a mobile management system using declarative management and for the most part it is pretty great. There is one consistent issue I have run into and it comes when testing VPP app installs with not enough licenses.
When my server detects that it can't provide a license ID it will return a 404, which causes the rest of the DM syncing to stop, and the activation to throw an error.
Per the documentation for using simple activation:
An array of strings that specify the identifiers of configurations to install. A failure to install one of the configurations doesn’t prevent other configurations from installing
The above would imply that if a config fails it should not affect anything else (aside from possibly reporting an error.
Am I returning the wrong error code for it to continue or is the behavior correct and the documentation is wrong?
Any additional info would be useful
My app controls the cursor movement in a text view on iPhone and iPads.
On screen touch, the IOS cursor position is out of sync with the app cursor position.
Is there a way to find out, on screen touch, where the ios cursor positition is and update the app cursor to the ios cursor position?
When they are out of sync, the user has to move the cursor to the startIndex and navigate from there. Frustating!
I have looked at many programming books, forums, and internet search with nothing to no avail.
Any help will be greatly appreciated. The app names are SummaGramPhonex and SummaGramIPAD11 and SummaGramIPAD13.
Thanks. Charlie
3Sep25
We've observed an issue where the video button on the CallKit UI is disabled during Video VoIP calls.
This issue appears to be specific to notch devices running SDK 26 and iOS 26 beta 7, specifically on iPhone 11. We have not seen this behavior on devices with Dynamic Island or on older iOS versions.
For further details, please refer to the attached video and sysdiagnose file. : FB19827793
Our experimentation suggests this issue is exclusively present on non-Dynamic Island devices with iOS 26 beta.
Overview of Issue
My implementation of HealthKit is no longer able to read values due to authorization issues (ex. "HealthKitService: Not authorized to read HKQuantityTypeIdentifierHeight. Status: 0"). I have been through every conceivable debugging step including building a minimal project that just requests HealthKit data and the issue has persisted. I've tried my personal as well as Organizational developer teams. My MacOS and Mac Mini. Simulator and personal device. Rechecked entitlements, reprovisioned certificates. This makes no sense. And I have been unable to find anything similar in the Developer forums or documentation.
The problem occurs during the onboarding flow when the app requests HealthKit permissions. Even when the user grants permission in the HealthKit authorization sheet, the authorizationStatus for characteristic data types (like Biological s3x and Date of Birth) and quantity data types (like Height and Weight) consistently returns as .sharingDenied. This prevents the app from pre-filling the user's profile with their HealthKit data, forcing them to enter it manually.
The issue seems to be environmental rather than a specific code bug, as it has been reproduced in a minimal test case app and persists despite extensive troubleshooting.
Minimal test project: https://github.com/ChristopherJones72521/HealthKitTestApp**
STEPS TO REPRODUCE
Build app, attempt to sign in. No data is imported into the respective fields in the main app. Console logs confirm.
PLATFORM AND VERSION
iOS
Development environment: Xcode Version 16.4 (16F6), macOS 15.5 (24F74)
Run-time configuration: iOS 18.5
Relevant Code Snippets
Here are the key pieces of code that illustrate the implementation and the problem:
1. Requesting HealthKit Permissions (HealthKitService.swift)
This function is called to request authorization for the required HealthKit data types. The typesToRead and typesToWrite are defined in a centralized HealthKitTypes struct.
// HealthKitService.swift
func requestPermissions(completion: @escaping (Bool, Error?) -> Void) {
guard HKHealthStore.isHealthDataAvailable() else {
completion(false, HealthKitError.notAvailable)
return
}
let typesToRead: Set<HKObjectType> = [
HKObjectType.characteristicType(forIdentifier: .dateOfBirth)!,
HKObjectType.characteristicType(forIdentifier: .biologicals3x)!,
HKObjectType.quantityType(forIdentifier: .height)!,
HKObjectType.quantityType(forIdentifier: .bodyMass)!
]
let typesToWrite: Set<HKSampleType> = [
HKObjectType.workoutType(),
HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!
]
healthStore.requestAuthorization(toShare: typesToWrite, read: typesToRead) { success, error in
DispatchQueue.main.async {
if let error = error {
print("HealthKitService: Error requesting authorization: \(error.localizedDescription)")
completion(false, error)
} else {
print("HealthKitService: Authorization request completed. Success: \(success)")
completion(success, nil)
}
}
}
}
2. Reading Biological s3x (HealthKitService.swift)
This function attempts to read the user's biological s3x. The print statements are included to show the authorization status check, which is where the issue is observed.
// HealthKitService.swift
func readBiologicals3x() async throws -> HKBiologicals3xObject? {
guard HKHealthStore.isHealthDataAvailable() else { throw HealthKitError.notAvailable }
let s3xAuthStatus = healthStore.authorizationStatus(for: HKObjectType.characteristicType(forIdentifier: .biologicals3x)!)
print("HealthKitService: Auth status for Biological s3x: \(s3xAuthStatus.rawValue)")
guard s3xAuthStatus == .sharingAuthorized else {
print("HealthKitService: Not authorized to read Biological s3x.")
throw HealthKitError.notAuthorized
}
do {
return try healthStore.biologicals3x()
} catch {
print("HealthKitService: Error executing biologicals3x query: \(error.localizedDescription)")
throw HealthKitError.queryFailed(error)
}
}
3. Calling HealthKit Functions During Onboarding (OnboardingFlowView.swift)
This is how the HealthKitService is used within the onboarding flow. The requestHealthKitAndPrefillData function is called after the user signs in, and it attempts to read the data to pre-fill the profile form.
// OnboardingFlowView.swift
func readHealthKitDataAsync() async {
print("Attempting to read HealthKit data async...")
// ... (calls to HealthKitService.shared.readDateOfBirth(), readHeight(), etc.)
do {
if let biologicals3xObject = try await HealthKitService.shared.readBiologicals3x() {
if self.selectedGender == nil {
switch biologicals3xObject.biologicals3x {
case .female: self.selectedGender = .female
case .male: self.selectedGender = .male
case .other: self.selectedGender = .other
default:
break
}
}
}
} catch {
print("OnboardingFlowView: Error reading Biological s3x: (error.localizedDescription)")
}
print("OnboardingFlowView: Finished HealthKit data processing.")
}
Console Logs
Attempting to read HealthKit data async...
HealthKitService: Reading Date of Birth...
HealthKitService: Current auth status for DOB (during read attempt): 0
HealthKitService: Not authorized to read Date of Birth. Status: 0
OnboardingFlowView: Error reading Date of Birth: The operation couldn’t be completed. (Strike_Force.HealthKitError error 2.)
HealthKitService: Reading Height...
HealthKitService: Current auth status for HKQuantityTypeIdentifierHeight (during read attempt): 0
HealthKitService: Not authorized to read HKQuantityTypeIdentifierHeight. Status: 0
OnboardingFlowView: Error reading Height: The operation couldn’t be completed. (Strike_Force.HealthKitError error 2.)
HealthKitService: Reading Weight (Body Mass)...
HealthKitService: Current auth status for HKQuantityTypeIdentifierBodyMass (during read attempt): 0
HealthKitService: Not authorized to read HKQuantityTypeIdentifierBodyMass. Status: 0
OnboardingFlowView: Error reading Weight: The operation couldn’t be completed. (Strike_Force.HealthKitError error 2.)
HealthKitService: Pre-read check for Biologicals3x auth status: 1 (Denied)
HealthKitService: Reading Biological s3x...
HealthKitService: Current auth status for Biological s3x (during read attempt): 1
HealthKitService: Not authorized to read Biological s3x. Status: 1
OnboardingFlowView: Error reading Biological s3x: The operation couldn’t be completed. (Strike_Force.HealthKitError error 2.)
I've noticed that when I'm in a moving vehicle going faster than 15 mph I can't tap a WhatsApp message and get the contextual menu (copy, forward etc). It's like the app or iOS disregards the tactile input above 15 mph.
I need to try it with other apps to see if it happens with them. I'm guessing it's an iOS thing because I doubt WhatsApp has access to the speed value from the GPS. Maybe that's not a correct assumption.
It's really a pain when you can't get the contextual menu to pop up. Can the feature that blocks popup menus at speeds above 15 mph be turned off?
I'm not sure at which beta it happened, but somewhere during the iOS 26 Public Beta releases, my iCloud Contacts have duplicated close to 100 times each. When I scroll to the bottom of the list to try and manage duplicates, it indicates I only have 2 duplicates. I should be sitting around 350 contacts and instead, I now have over 10k.
Anyone else with this issue? I have filed Feedback in the app. I'm not certain if it was related to iOS 26 or iPadOS 26 as I have both, but noticed it first on my iPhone. I confirmed that the issue has affected my iCloud Contacts and therefore all of my Apple devices included older iOS and MacOS versions. Short of manually deleting all the duplicates, I'm at a loss as to how I can correct his.
Hi everyone, I'm using an app group to share data between iOS and it's watch companion app.
I ensured that is has the same identifier in Signing & Capabilities and in the .entitlements files.
Here is the UserDefaults part:
class UserDefaultsManager {
private let suitName = "group.com.sanjeevbalakrishnan.Test"
public func saveItems(_ items: [ItemDTO]) {
print("Save \(items.count) items to shared defaults")
let defaults = UserDefaults(suiteName: suitName)
let data = try? JSONEncoder().encode(items)
defaults?.set(data, forKey: "items")
}
public func loadItems() -> [ItemDTO] {
let defaults = UserDefaults(suiteName: suitName)
print(defaults)
guard let data = defaults?.data(forKey: "items") else {
print("watchOS received data is empty")
return []
}
let items = [ItemDTO].from(data: data)
print("Load \(items.count) items from user defaults")
return items
}
}
For testing I called loadItems after saveItems on iOS app and it returned items. However, on watchOS app it always returns empty array.
What do I need to consider?
Thanks.
Best regards
Sanjeev
Hello,
We are currently developing an application that uses the Host-based Card Emulation (HCE) entitlement to enable corporate access functionality. With this entitlement, we have successfully established HCE communication and can interact with our access control systems to unlock doors.
Our question is related to improving the user experience:
We would like this access functionality to work without requiring the app to be in the foreground, as this adds friction for users during entry.
Specifically, we would like to know:
Is it possible for our app to coexist with Apple Wallet as the default contactless app, so that:
Our app handles NFC interactions for corporate access (e.g., opening doors).
Apple Wallet remains the default for payments.
If that coexistence is not possible, and our app is set as the default contactless app,
Will the system still need to launch our app into the foreground to complete a transaction (e.g., to emulate the NFC card)?
Or is there a way to trigger HCE responses in the background (e.g., using a background process or service extension)?
Any guidance on how to configure the app for optimal background access behavior, while maintaining compatibility with Wallet, would be greatly appreciated.
Thank you in advance.
We are using a column style split view controller as root view of our app and in iOS26 the navigation titles of primary and supplementary view controllers are not visible and secondary view controller title is displayed in supplementary column.
Looks the split view hidden all the child view controllers title and shown the secondary view title as global in macCatlayst. The right and left barbutton items are showing properly for individual view controllers.
Facing this weird issue in iOS26 betas. The secondary navigation title also visible only when WindowScene,titlebar.titleVisibility is not hidden.
Kindly suggest the fix for this issue as we can't use the secondary view navigation title for showing supplementary view's data. The issue not arises in old style split views or when the split view embedded in another splitView.
Refer the sample code and attachment here
let splitView = UISplitViewController(style: .tripleColumn)
splitView.preferredDisplayMode = .twoBesideSecondary
splitView.setViewController(SplitViewChildVc(title: "Primary"), for: .primary)
splitView.setViewController(SplitViewChildVc(title: "Supplementary"), for: .supplementary)
splitView.setViewController(SplitViewChildVc(title: "Secondary"), for: .secondary)
class SplitViewChildVc: UIViewController {
let viewTitle: String
init(title: String = "Default") {
self.viewTitle = title
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = viewTitle
self.navigationItem.title = viewTitle
if #available(iOS 26.0, *) {
navigationItem.subtitle = "Subtitle"
}
let leftbutton = UIBarButtonItem(barButtonSystemItem: .cancel, target: nil, action: nil)
navigationItem.leftBarButtonItem = leftbutton
let rightbutton = UIBarButtonItem(barButtonSystemItem: .add, target: nil, action: nil)
navigationItem.rightBarButtonItem = rightbutton
}
}
Hello,
I hope you're all doing well! I'm currently working on integrating new iOS 26 features into my app, and so far, the process has been really exciting. However, I've encountered an issue when updating the badge of a UIBarButtonItem, and I’m hoping to get some insights or suggestions.
The app has two UIViewController instances in the navigation stack, each containing a UIBarButtonItem.
On the first controller, the badge is set to 1, and on the second, the badge is set to 2. In the second controller, there is a "Reset" button that sets the badge of the second controller to nil.
However, when I tap the "Reset" button, instead of setting the badge to nil, it sets the value to 1.
I would appreciate any ideas or suggestions on how to solve this problem. Maybe I am using the badge API incorrectly.
Thank you!
class ViewController: UIViewController {
var cartButtonItem: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
configureNavigationItem()
}
func configureNavigationItem() {
cartButtonItem = UIBarButtonItem(image: UIImage(resource: .cartNavBar), style: .plain, target: self, action: #selector(showCartTab))
cartButtonItem.tintColor = UIColor.systemBlue
cartButtonItem.badge = .count(1)
navigationItem.rightBarButtonItem = cartButtonItem
}
@objc func showCartTab() {
// Add second view controller in navigation stack
performSegue(withIdentifier: "Cart", sender: nil)
}
}
class CartViewController: UIViewController {
var cartButtonItem: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
configureNavigationItem()
}
func configureNavigationItem() {
cartButtonItem = UIBarButtonItem(image: UIImage(resource: .cartNavBar), style: .plain, target: nil, action: nil)
cartButtonItem.tintColor = UIColor.systemBlue
cartButtonItem.badge = .count(2)
navigationItem.rightBarButtonItem = cartButtonItem
}
func updateBadge() {
cartButtonItem.badge = nil
}
@IBAction func resetButtonPressed(_ sender: Any) {
updateBadge()
}
}
Hello Apple forum !
I spotted a weird behaviour with LazyVStack in a ScrollView. I understand that it loads its views only once upon appearance unlinke VStack that loads everything in one shot.
What I noticed also, it seems to reload its views sometimes when scrolling back up to earlier loaded views. The thing is, it isn't always the case.
struct LazyVStackTest: View {
var body: some View {
ScrollView {
LazyVStack {
ForEach(0..<1000, id: \.self) { _ in
// if true {
MyText()
// }
}
}
}
}
struct MyText: View {
var body: some View {
let _ = Self._printChanges()
HStack {
Text("hello")
}
}
}
}
If we consider the code above on XCode 26 beta 7 on an iOS 26 or iOS 18.2 simulator.
Scroll to the bottom : you'll see one "LazyVStackTest.MyText: @self changed" for each row.
Then scroll back up to the top, we'll see again the same message printed multiple times.
--> So I gather from this that LazyVStack not only loads lazily but also removes old rows from memory & recreates them upon reappearance.
What I don't get however is that if you uncomment the "if true" statement, you won't see the reloading happening. And I have absolutely no clue as to why 😅
If someone could help shed some light on this weird behaviour, it would be greatly appreciated ^^
PS : the issue is also present with XCode 16.2 but at a deeper lever (ex: if we embed another custom View "MyText2" inside "MyText", the reloading is in "MyText2" & not "MyText")
I want to be able to disable all liquid glass effects from my Navigation bar, and it's bar buttons. But I still want to be able to have the liquid glass effect on my UITabbar.
Is there a way to disable glass effects from navbar and still retain them all for tabbars using UIKit?
I created a Radar for this FB14766095, but thought I would add it here for extra visibility, or if anyone else had any thoughts on the issue.
Basic Information
Please provide a descriptive title for your feedback:
iOS 18 hit testing functionality differs from iOS 17
What type of feedback are you reporting?
Incorrect/Unexpected Behavior
Description:
Please describe the issue and what steps we can take to reproduce it:
We have an issue in iOS 18 Beta 6 where hit testing functionality differs from the expected functionality in iOS 17.5.1 and previous versions of iOS.
iOS 17: When a sheet is presented, the hit-testing logic considers subviews of the root view, meaning the rootView itself is rarely the hit view.
iOS 18: When a sheet is presented, the hit-testing logic changes, sometimes considering the rootView itself as the hit view.
Code:
import SwiftUI
struct ContentView: View {
@State var isPresentingView: Bool = false
var body: some View {
VStack {
Text("View One")
Button {
isPresentingView.toggle()
} label: {
Text("Present View Two")
}
}
.padding()
.sheet(isPresented: $isPresentingView) {
ContentViewTwo()
}
}
}
#Preview {
ContentView()
}
struct ContentViewTwo: View {
@State var isPresentingView: Bool = false
var body: some View {
VStack {
Text("View Two")
}
.padding()
}
}
extension UIWindow {
public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
/// Get view from superclass.
guard let hitView = super.hitTest(point, with: event) else { return nil }
print("RPTEST rootViewController = ", rootViewController.hashValue)
print("RPTEST rootViewController?.view = ", rootViewController?.view.hashValue)
print("RPTEST hitView = ", hitView.hashValue)
if let rootView = rootViewController?.view {
print("RPTEST rootViewController's view memory address: \(Unmanaged.passUnretained(rootView).toOpaque())")
print("RPTEST hitView memory address: \(Unmanaged.passUnretained(hitView).toOpaque())")
print("RPTEST Are they equal? \(rootView == hitView)")
}
/// If the returned view is the `UIHostingController`'s view, ignore.
print("MTEST: hitTest rootViewController?.view == hitView", rootViewController?.view == hitView)
print("MTEST: -")
return hitView
}
}
Looking at the print statements from the provided sample project:
iOS 17 presenting a sheet from a button tap on the ContentView():
RPTEST rootViewController's view memory address: 0x0000000120009200
RPTEST hitView memory address: 0x000000011fd25000
RPTEST Are they equal? false
MTEST: hitTest rootViewController?.view == hitView false
RPTEST rootViewController's view memory address: 0x0000000120009200
RPTEST hitView memory address: 0x000000011fd25000
RPTEST Are they equal? false
MTEST: hitTest rootViewController?.view == hitView false
iOS 17 dismiss from presented view:
RPTEST rootViewController's view memory address: 0x0000000120009200
RPTEST hitView memory address: 0x000000011fe04080
RPTEST Are they equal? false
MTEST: hitTest rootViewController?.view == hitView false
RPTEST rootViewController's view memory address: 0x0000000120009200
RPTEST hitView memory address: 0x000000011fe04080
RPTEST Are they equal? false
MTEST: hitTest rootViewController?.view == hitView false
iOS 18 presenting a sheet from a button tap on the ContentView():
RPTEST rootViewController's view memory address: 0x000000010333e3c0
RPTEST hitView memory address: 0x0000000103342080
RPTEST Are they equal? false
MTEST: hitTest rootViewController?.view == hitView false
RPTEST rootViewController's view memory address: 0x000000010333e3c0
RPTEST hitView memory address: 0x000000010333e3c0
RPTEST Are they equal? true
MTEST: hitTest rootViewController?.view == hitView true
You can see here ☝️ that in iOS 18 the views have the same memory address on the second call and are evaluated to be the same. This differs from iOS 17.
iOS 18 dismiss
RPTEST rootViewController's view memory address: 0x000000010333e3c0
RPTEST hitView memory address: 0x0000000103e80000
RPTEST Are they equal? false
MTEST: hitTest rootViewController?.view == hitView false
RPTEST rootViewController's view memory address: 0x000000010333e3c0
RPTEST hitView memory address: 0x0000000103e80000
RPTEST Are they equal? false
MTEST: hitTest rootViewController?.view == hitView false
The question I want to ask:
Is this an intended change, meaning the current functionality in iOS 18 is expected?
Or is this a bug and it's something that needs to be fixed?
As a user, I would expect that the hit testing functionality would remain the same from iOS 17 to iOS 18.
Thank you for your time.
Development environment
Xcode 26.0 Beta 6
iOS 26 Simulator
macOS 15.6.1
To verify TLS 1.3 session resumption behavior in URLSession, I configured URLSessionConfiguration as follows and sent an HTTP GET request:
let config = URLSessionConfiguration.ephemeral
config.tlsMinimumSupportedProtocolVersion = .TLSv13
config.tlsMaximumSupportedProtocolVersion = .TLSv13
config.httpMaximumConnectionsPerHost = 1
config.httpAdditionalHeaders = ["Connection": "close"]
config.enablesEarlyData = true
let session = URLSession(configuration: config, delegate: nil, delegateQueue: nil)
let url = URL(string: "https://www.google.com")!
var request = URLRequest(url: url)
request.assumesHTTP3Capable = true
request.httpMethod = "GET"
let task = session.dataTask(with: request) { data, response, error in
if let error = error {
print("Error during URLSession data task: \(error)")
return
}
if let data = data, let responseString = String(data: data, encoding: .utf8) {
print("Received data via URLSession: \(responseString)")
} else {
print("No data received or data is not UTF-8 encoded")
}
}
task.resume()
However, after capturing the packets, I found that the ClientHello packet did not include the early_data extension.
It seems that enablesEarlyData on URLSessionConfiguration is not being applied.
How can I make this work properly?
When changing a camera's exposure, AVFoundation provides a callback which offers the timestamp of the first frame captured with the new exposure duration: AVCaptureDevice.setExposureModeCustom(duration:, iso:, completionHandler:).
I want to get a similar callback when changing frame duration.
After setting AVCaptureDevice.activeVideoMinFrameDuration or AVCaptureDevice.activeVideoMinFrameDuration to a new value, how can I compute the index or the timestamp of the first camera frame which was captured using the newly set frame duration?
On iPhone, I would like to have a more button at the top right of the navigation bar, a search field in the bottom toolbar, and a plus button to the right of the search field. I've achieved this via the code below.
But on iPad they should be in the navigation bar at the trailing edge from left to right: plus, more, search field. Just like the Shortcuts app, if there's not enough horizontal space, the search field should collapse into a button, and with even smaller space the search bar should become full-width under the navigation bar.
Right now on iPad the search bar is full width under the navigation bar, more at top right, plus at bottom middle, no matter how big the window is.
How can I achieve that? Any way to specify them for the system to more automatically do the right thing, or would I need to check specifically for iPhone vs iPad UIDevice to change the code?
struct ContentView: View {
@State private var searchText = ""
var body: some View {
NavigationStack {
VStack {
Text("Hello, world!")
}
.navigationTitle("Test App")
.searchable(text: $searchText)
.toolbar {
ToolbarItem {
Menu {
//...
} label: {
Label("More", systemImage: "ellipsis")
}
}
DefaultToolbarItem(kind: .search, placement: .bottomBar)
ToolbarSpacer(.fixed, placement: .bottomBar)
ToolbarItem(placement: .bottomBar) {
Button {
print("Add tapped")
} label: {
Label("Add", systemImage: "plus")
}
}
}
}
}
}