UITabBarController
|
|
VC_Tab1 --------------------------- VC_Tab2
| |
| |
VC_Tab1_Child VC_Tab2_Child
|
(HeaderView)
|
(MyButton)
The structure of the view controllers and views in the project is as described above.
<case 1>
self.navigationController?.popToRootViewController(animated: false)
tabBarController.selectedIndex = 1
When popToRootViewController(animated: false) is called in VC_Tab1_Child, followed by setting the tab controller’s selectedIndex = 1, the following results are observed:
viewWillAppear(_:), <VC_Tab2_Child>
deinit, <VC_Tab1_Child>
viewDidAppear(_:), <VC_Tab2_Child>
The originally expected results are as follows
viewWillDisappear(_:), <VC_Tab1_Child>
viewDidDisappear(_:), <VC_Tab1_Child>
deinit, <VC_Tab1_Child>
deinit, <HeaderView>
deinit, <MyButton>
headerView.backButton.rx.tap -> Event completed
headerView.backButton.rx.tap -> isDisposed
viewWillAppear(_:), <VC_Tab2_Child>
viewDidAppear(_:), <VC_Tab2_Child>
The HeaderView belonging to VC_Tab1_Child was not deallocated, and the resources associated with that view were also not released. Similarly, VC_Tab1_Child.viewWillDisappear and VC_Tab1_Child.didDisappear were not called.
<case 2>
self.navigationController?.popToRootViewController(animated: false)
DispatchQueue.main.async {
tabBarController.selectedIndex = 1
}
After performing the pop operation as shown in the code and waiting for a short period before testing, the expected results were generally achieved. (However, rarely, the results were similar to those observed when called without async.)”
<case 3>
self.navigationController?.popToRootViewController(animated: false)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
tabBarController.selectedIndex = 1
}
When a sufficient delay was ensured as described above, the expected results were achieved 100% of the time.”
The abnormal behavior is more pronounced in iOS versions prior to 18 and varies depending on the iOS version.
I couldn’t find any documentation explaining the unexpected behavior shown in the results above. What could be the cause? The simulation code is provided below.
https://github.com/linusix/UITabBarController_Test2
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
According to the MVVM design pattern, one of my views depends on many properties in my model. Can I use logic like @published var model = MyModel()? Will there be a large performance loss? Will the UI be refreshed when other unrelated properties in the model are modified? What is the best practice in this case?
Topic:
UI Frameworks
SubTopic:
General
When I present a UIDocumentPickerViewController I want it to occupy the fullscreen but it never displays as fullscreen
The modalPresentationStyle seems to have no effect no matter what I set it to
Running the code with DispatchQueue.main.async did not help either
Here is the code
Anybody got any suggestions?
`@objc private func plusButtonPressed() {
DispatchQueue.main.async {
let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeData as String], in: .import)
picker.delegate = self
picker.modalPresentationStyle = .fullScreen
self.present(picker, animated: true)
}
}`
I have an observable object which is a model a view.
I also have a Tip (from TipKit) with @Parameter and a rule.
The source of truth for the state is in the observable object, however the Tip needs to be updated when state changes. So how do I bind between the two?
The way I was thinking was to sink updates from objectWillChange and check if Tips parameter needs to be updated or add didSet if it a @Published property. But I am not sure this is the best practice.
Schematic example:
class MyModel: ObservableObject {
struct TapSubmitTip: Tip {
@Parameter static var isSubmitButtonEnabled: Bool = false
var title: Text {
Text("Tap \"Submit\" to confirm your selection.")
}
var rules: [Rule] {
#Rule(Self.$isSubmitButtonEnabled) {
$0 == true
}
}
}
let tapSubmitTip = TapSubmitTip()
var objectWillChangeCancallable: AnyCancellable!
// Used by the view to enable or disable the button
var isSubmitButtonEnabled: Bool {
// Some logic to determine if button should be enabled.
}
init() {
objectWillChangeCancallable = objectWillChange.sink { [weak self] void in
guard let self else { return }
if isSubmitButtonEnabled {
TapSubmitTip.isSubmitButtonEnabled = true
}
}
}
...
// Call objectWillChange or update published properties as needed.
...
}
Hi! I'm attempting to run the Quakes Sample App^1 from macOS. I am running breakpoints and confirming the mapCameraKeyframeAnimator is being called:
.mapCameraKeyframeAnimator(trigger: selectedId) { initialCamera in
let start = initialCamera.centerCoordinate
let end = quakes[selectedId]?.location.coordinate ?? start
let travelDistance = start.distance(to: end)
let duration = max(min(travelDistance / 30, 5), 1)
let finalAltitude = travelDistance > 20 ? 3_000_000 : min(initialCamera.distance, 3_000_000)
let middleAltitude = finalAltitude * max(min(travelDistance / 5, 1.5), 1)
KeyframeTrack(\MapCamera.centerCoordinate) {
CubicKeyframe(end, duration: duration)
}
KeyframeTrack(\MapCamera.distance) {
CubicKeyframe(middleAltitude, duration: duration / 2)
CubicKeyframe(finalAltitude, duration: duration / 2)
}
}
But I don't actually see any map animations taking place when that selection changes.
Running the application from iPhone simulator does show the animations.
I am building from Xcode Version 16.2 and macOS 15.2. Are there known issues with this API on macOS?
Not sure what could cause this. the UI align differently running on iPhone versus running on Mac. If I remove the HStack, it works but I still would like to know why, and if there is a way to make it right on both platforms.
Thank you
here is my code
@State private var viewModel = FirmwareSelectionViewModel()
var body: some View {
Form {
Section("Setup Name") {
TextField ( "", text: $viewModel.setupName )
.foregroundColor(.green )
.disableAutocorrection(true)
.onSubmit {
print ("On Submit")
}
}
Section("Battery") {
HStack() {
Text("Volt")
TextField("", value: $viewModel.Vnominal, format: .number)
.textFieldStyle(.roundedBorder)
.foregroundColor(.green )
#if !os(macOS)
.keyboardType(.decimalPad)
#endif
.onChange(of: viewModel.Vnominal) {
viewModel.checkEntryValidity()
print("Updated Vnominal: \(viewModel.Vnominal)")
}
Text("Ah")
TextField("", value: $viewModel.batteryCapacity, format: .number)
.textFieldStyle(.roundedBorder)
.foregroundColor(.green )
#if !os(macOS)
.keyboardType(.decimalPad)
#endif
.onChange(of: viewModel.batteryCapacity) {
viewModel.checkEntryValidity()
print("Updated Battery Capacity: \(viewModel.batteryCapacity)")
}
}
}
Section("Firmware Type") {
Picker(selection: $viewModel.selectedType, label: EmptyView()) {
ForEach(TypeOfFirmware.allCases) { type in
Text(type.rawValue).tag(type as TypeOfFirmware)
.foregroundColor(.green )
}
}
.pickerStyle(SegmentedPickerStyle())
Picker(selection: $viewModel.selectedFirmware, label: EmptyView()) {
ForEach(viewModel.availableFirmware) { firmware in
Text(firmware.rawValue.capitalized).tag(firmware as Firmware)
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
.onChange(of: viewModel.selectedType) {
viewModel.resetFirmwareSelection()
}
.navigationTitle("Firmware Selection")
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
I set the isHidden property of a view in traitCollectionDidChange and found that sometime it does not take effect after being set(value of isHidden actually not changed either). It looks like the setting does not take effect when triggered an even number of times, but it is normal when triggered an odd number of times.
When setting isHidden, what actually goes into is [UIView (Rendering) setHidden:], which internally calls [UIView _ bitFlagValueAfterIncrementingHiddenManagement CountForKey: withIncrement: bitFlagValue:] to handle the relevant logic of "_UIViewPendingHiddenCount". Is this issue related to this part of the processing? returning 0 after calling seems normal
This view is a UIStackView, and it is uncertain whether it is related to the type of view
Hello,
I’m encountering the error "Publishing changes from within view updates is not allowed, this will cause undefined behavior". while developing an app using SwiftUI and ARKit.
I have a ObjectTracking class where I update some @Published variables inside a function called processObjectAttributes after detecting objects. However, when I try to update these state variables in the View (like isPositionChecked, etc.), the error keeps appearing.
Here is a simplified version of my code:
class ObjectTracking: ObservableObject {
@Published var isPositionChecked: Bool = false
@Published var isSizeChecked: Bool = false
@Published var isOrientationChecked: Bool = false
func checkAttributes(objectAnchor: ARObjectAnchor,
_ left: ARObjectAnchor.AttributeLocation,
_ right: ARObjectAnchor.AttributeLocation? = nil,
threshold: Float) -> Bool {
let attributes = objectAnchor.attributes
guard let leftValue = attributes[left]?.floatValue else { return false }
let rightValue = right != nil ? attributes[right!]?.floatValue ?? 0 : 0
return leftValue > threshold && (right == nil || rightValue > threshold)
}
func isComplete(objectAnchor: ARObjectAnchor) -> Bool {
isPositionChecked = checkAttributes(objectAnchor: objectAnchor, .positionLeft, .positionRight, threshold: 0.5)
isSizeChecked = checkAttributes(objectAnchor: objectAnchor, .sizeLeft, .sizeRight, threshold: 0.3)
isOrientationChecked = checkAttributes(objectAnchor: objectAnchor, .orientationLeft, .orientationRight, threshold: 0.3)
return isPositionChecked && isSizeChecked && isOrientationChecked
}
func processObjectAttributes(objectAnchor: ARObjectAnchor) {
currentObjectAnchor = objectAnchor
}
}
In my View, I am using @ObservedObject to observe the state of these variables, but the error persists when I try to update them during view rendering.
Could anyone help me understand why this error occurs and how to avoid it? I understand that state should not be updated during view rendering, but I can’t find a solution that works in this case.
Thank you in advance for your help!
Our MacOS app has for some time been able to create so-called "add-on" services, which are dynamically written to individual bundles in ~/Library/Services/ (as opposed to being statically defined in the app's Info.plist). These worked fine for a long time until recently. They still appear in other app Services menus, but do not get as far as calling the specified instance method in our app. Does anyone know if add-on services are no longer supported? Perhaps due to some new security constraint? The documentation on app services in general seems to be out of date.
I did try copying the add-on service definition from the add-on plist into the app's Info.plist. That seemed to work, so the basic specification doesn't seem to have changed.
Topic:
UI Frameworks
SubTopic:
AppKit
I'm developing a grid of focusable elements in SwiftUI with different sizes for tvOS (similar to a tv channel grid).
Because the Focus Engine calculates the next view to focus based on the center of the currently focused view, sometimes it changes focus to an unexpected view. Here's an example:
Actual:
Expected:
Is it possible to customize the anchor point from which the focus engine traces a ray to the next view? I would prefer the leading edge in my case.
Hello Apple Developer Community,
I am encountering an issue with app icon rendering after updating an app on devices running iOS 18 or newer. Below are the details:
Issue Summary:
When updating an app from a previous version (with separate light and dark mode icons) to the latest version (where both modes use the same icon), the icon changes are not reflected consistently across all system menus.
Steps to Reproduce:
Set the device mode to Dark Mode.
Install the previous app version (with different icons for light and dark modes).
Update the app to the latest version (where both modes use the same icon).
Change the device mode to Light Mode.
Switch back to Dark Mode.
Expected Behavior:
The app icon should remain consistent across all system menus (Home Screen, Spotlight search, etc.) when switching between Light and Dark Modes.
Observed Behavior:
The app icon displays correctly on the Home Screen but inconsistencies appear in other menus, such as Spotlight search or when toggling between modes.
For instance, in Dark Mode, the icon may revert to the previous black-colored logo or display incorrectly compared to the updated design.
Additional Notes:
The asset catalog is configured correctly, with identical icons set for both light and dark modes in the latest app version.
Incrementing the build number was implemented during the update.
A manual device restart resolves the issue on some devices, but not consistently.
Questions for the Community:
Has anyone else experienced similar app icon caching or rendering issues in iOS 18 or later?
Are there known workarounds or specific configurations to ensure consistent icon rendering across all system menus?
Could this be related to iOS 18's icon caching or appearance handling mechanisms?
Your insights and suggestions would be greatly appreciated. Thank you for your time!
Hi,
I am having some spacing issues with the new TabViewStyle.sidebarAdaptable. My app uses @ToolBarContentBuilder for navigationBar elements as there are some custom design requirements. One of these is title text that is set in the principal position.
Simplified example:
var body: some View {
Text("Body")
.toolbar {
toolbar()
}
}
@ToolbarContentBuilder
private func toolbar() -> some ToolbarContent {
ToolbarItem(placement: placement) {
Text("Title")
}
}
Everything with this setup works fine till I use an iPad with iOS 18 where the new toggleable sidebar is present. Upon switching to the sidebar layout the title does not move to the space adjacent to the navigation button (where the tab bar just was) and instead remains in its own bar, below the rest of the navigation.
I've noticed that when navigationTitle is set the the title set in toolbar() does appear in the right place.
var body: some View {
Text("Body")
.toolbar {
toolbar()
}
.navigationTitle("anything")
}
Is this expected behaviour? How can I achieve a single line nav bar with a title set this way?
Happy to provide a sandbox app to reproduce this issue.
Many thanks,
Matt
I have a SwiftUI view of the form
struct ContentView: View {
// ...
.onDrop(of: [.pdf], isTargeted: $isDropTargeted) { pdfs in
for pdf in pdfs {
I'm just not sure what to do next, I see there's a loadPreviewImage() that if I use like:
Task.detached {
// returns any NSSecureCoding object
let image = try! await pdf.loadPreviewImage()
}
Not sure how I'm supposed to get my preview image from that NSSecureCoding object
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hi everyone,
I've come across an issue on iOS that seems to affect many apps. Here's what happens:
A user logs in with correct credentials and proceeds to the OTP verification screen as part of multi factor authentication.
iOS presents the system password save prompt ("Would you like to save this password?").
Without selecting an option on this prompt, the user backgrounds the app (e.g., to check their email for the OTP).
Upon returning to the app, the keyboard becomes completely inaccessible on the OTP screen or any other screen.
From my testing, this behavior appears to be an OS-level bug, as it occurs consistently across various apps. Has anyone else encountered this? Any known workarounds or updates from Apple on this behavior would be greatly appreciated!
Thanks!
Topic:
UI Frameworks
SubTopic:
UIKit
I want to get the content present in a note or a mail thread when my cursor is in it on macos. (In the focused element).
But I don't succeed to get any element from both mail and notes using :
let result = AXUIElementCopyAttributeValue(appRef, kAXFocusedUIElementAttribute as CFString, &focusedElement)
Even when I want to check the available attribute :
let result = AXUIElementCopyAttributeNames(element, &attributeNames)
I got AXUIElementCopyAttributeNames result: AXError(rawValue: -25204)
But I have the write permission because when I am running AXIsProcessTrusted() to see if I got accessible permission it don't throw an error
Is it possible to do it that way or I have to change
Hi,
I have the following swiftUI code:
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.colorEffect(ShaderLibrary.AlphaConvert())
and the following shader:
[[ stitchable ]] half4 AlphaConvert(float2 position, half4 currentColor) {
return half4(currentColor.r>0.5,currentColor.r<=0.5,0,(currentColor.r>0.5));
}
I am loading a full-res image from my photo library (24MP)... The image initially displays fine, with portions of the image red, and the rest black (due to alpha blending)... However, after rotating the device, I get an image that is a combination of red&green... Note, that the green pixels from the shader have alpha 0, hence, should never be seen. Is there something special that needs to be done on orientation changes so that the shader works fine?
Hi,
the new style of tab bar is at top, sort of a picker style , how to enforce SwiftUI to use it in old style fashion at bottom in iPadOS same as iOS ?
—
Kind Regards
Topic:
UI Frameworks
SubTopic:
SwiftUI
ScrollView scrolling works on Mac Catalyst apps with a Trackpad just fine but the same cannot be said for mouses with scroll wheels.
Is there any way to achieve scrolling with scroll wheels?
Consider this code:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
EmptyView()
}
}
}
Which looks like this:
How can I prevent the sidebar from being resized by a mouse and from being hidden?
P.S. Can consider using AppKit if it can help.
Let's say I have a model like this:
@Model
final class DataModel {
var firstProperty: String = ""
}
Later on I create a new property as such:
@Model
final class DataModel {
enum DataEnum {
case dataCase
}
var firstProperty: String = ""
var secondProperty: DataEnum? = .dataCase
}
My expectation is for the data that is already stored, the secondProperty would be added with a default value of .dataCase. However, it's being set to nil instead. I could have sworn it would set to the default value given to it. Has that changed, or has it always been this way? Does this require a migration plan?