Hi there, I'm currently using UIHostingController to display swift charts in uikit. The problem im facing is that the UIHostingController isn't outputting the intended theme. When the simulator/phone is on dark mode the view is still in light mode. Iv'e tried to force the view to use dark mode with:
.environment(\.colorScheme, .dark)
But it doesn't seem to help. Here's how I implement the UIHostingController to my view:
let controller = UIHostingController(rootView: StatVC())
controller.view.translatesAutoresizingMaksIntoConstraints = false
addChild(controller)
controller.didMove(toParent: self)
view.addSubview(controller.view)
where StatVC() is the swiftui view which contains the swift chart.
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Post
Replies
Boosts
Views
Activity
I would like to include the bottom sheet from the iPhone "find my" and "maps" app in my app. During my research I came across the new modifier .presentationDetents for sheets. The only problem here is that you can no longer interact with the main screen when the sheet is active. In my app, however, I would like the sheet to be active all the time like in the iPhone apps mentioned and that you can still interact with the main screen like in the iPhone apps with the map. I would be very happy about help. Greetings
I'm seeing a runtime warning in Xcode 14 Beta 5 that says "This method should not be called on the main thread as it may lead to UI unresponsiveness."
This is happening on the @main entry point of my app. See below:
The warning shown gives me no insight into what's actually going wrong. I think it may be due to some Core Location code that runs when the app first opens, but is there a way for me to get some more insight into what's causing this?
Or is this possibly an Xcode 14/iOS 16 bug, and this is not an issue to worry about? I'm not getting any warnings on Xcode 13/iOS 15.
I'd like to use .fullScreenCover() or .sheet() to present a View, depending on the current horizontalSizeClass.
If starting the following code in an iPhone (in portrait mode = .compact) or in an iPad (= .regular), the View is correctly displayed in a Sheet (iPhone) or in a FullScreenCover (iPad).
However when using SplitScreen mode on an iPad (and thus switching between .compact and .regular the View remains in the container it was originally displayed.
How can I correctly update this when switching between sizes on-the-fly?
struct ContentView: View {
@Environment(\.horizontalSizeClass) var horizontalSizeClass
var body: some View {
Group {
Text("hidden behind modal")
}
.modal(isPresented: .constant(true)) {
if horizontalSizeClass == .regular {
Rectangle()
.fill(Color.red)
.edgesIgnoringSafeArea(.all)
} else {
Rectangle()
.fill(Color.blue)
.edgesIgnoringSafeArea(.all)
}
}
}
}
struct Modal<ModalContent: View>: ViewModifier {
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@Binding var isPresented: Bool
@ViewBuilder let modalContent: ModalContent
func body(content: Content) -> some View {
if horizontalSizeClass == .regular {
content
.fullScreenCover(isPresented: $isPresented) {
modalContent
.overlay {
Text("horizontalSizeClass: regular")
}
}
} else {
content
.sheet(isPresented: $isPresented) {
modalContent
.overlay {
Text("horizontalSizeClass: compact")
}
}
}
}
}
extension View {
public func modal<Content: View>(isPresented: Binding<Bool>, @ViewBuilder content: @escaping () -> Content) -> some View {
modifier(Modal(isPresented: isPresented, modalContent: content))
}
}
Hi there!
After a few months off, I'm starting a new app.
I'm making a TabView like this:
import SwiftUI
struct ContentView: View {
@State private var tab: Tab = .adventures
var body: some View {
TabView(selection: $tab) {
Text("Explore")
.tag(Tab.explore)
.tabItem {
Label("Explore", systemImage: "airplane.circle")
}
Text("Profile")
.tag(Tab.profile)
.tabItem {
Label("Profile", systemImage: "person")
}
}
}
enum Tab {
case explore, profile
}
}
As you noticed, I want airplane.circle and person SF Symbols on the TabView but SwiftUI is showing airplane.circle.fill and person.fill in the preview canvas and also when I run the app in the simulator.
Why it is forcing me to show those icons?
Xcode version: 13.4.1
SF Symbols version: 3.3
iOS deployment target: 15.0
Thank you.
I'm having trouble getting the "Save to Files" option to work with ShareLink. Here's a simple example:
struct Item: Transferable {
public static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: .jpeg) { item in
// Write a jpeg to disk
let url = URL.documentsDirectory.appending(path: "item.jpeg")
let jpegData = UIImage(named: "testImg")!.jpegData(compressionQuality: 1)!
try! jpegData.write(to: url)
return SentTransferredFile(url)
}
}
}
struct ContentView: View {
var body: some View {
ShareLink(item: Item(), preview: SharePreview("Test Item"))
}
}
The ShareSheet presents all of the usual options, but tapping "Save to Files" briefly presents an empty modal before immediately dismissing.
The following errors are logged to the console:
2022-09-12 14:19:57.481592-0700 ExportTest[3468:1374472] [NSExtension] Extension request contains input items but the extension point does not specify a set of allowed payload classes. The extension point's NSExtensionContext subclass must implement `+_allowedItemPayloadClasses`. This must return the set of allowed NSExtensionItem payload classes. In future, this request will fail with an error.
2022-09-12 14:19:58.047009-0700 ExportTest[3468:1374472] [ShareSheet] cancelled request - error: The operation couldn’t be completed. Invalid argument
Sharing finished with error: Error Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" at SwiftUI/SharingActivityPickerBridge.swift:266
2022-09-12 14:19:58.584374-0700 ExportTest[3468:1379359] [AXRuntimeCommon] AX Lookup problem - errorCode:1100 error:Permission denied portName:'com.apple.iphone.axserver' PID:3472 (
0 AXRuntime 0x00000001ca77b024 _AXGetPortFromCache + 932
1 AXRuntime 0x00000001ca77d1d8 AXUIElementPerformFencedActionWithValue + 772
2 UIKit 0x00000002258b3284 3CB83860-AA42-3F9A-9B6E-2954BACE3DAC + 778884
3 libdispatch.dylib 0x0000000105078598 _dispatch_call_block_and_release + 32
4 libdispatch.dylib 0x000000010507a04c _dispatch_client_callout + 20
5 libdispatch.dylib 0x00000001050820fc _dispatch_lane_serial_drain + 988
6 libdispatch.dylib 0x0000000105082e24 _dispatch_lane_invoke + 420
7 libdispatch.dylib 0x000000010508fcac _dispatch_workloop_worker_thread + 740
8 libsystem_pthread.dylib 0x00000001ed9e8df8 _pthread_wqthread + 288
9 libsystem_pthread.dylib 0x00000001ed9e8b98 start_wqthread + 8
)
Additionally, this error is logged when the ShareSheet is first presented (before tapping Save to Files):
[ShareSheet] Couldn't load file URL for Collaboration Item Provider:<NSItemProvider: 0x282a1d650> {types = (
"public.jpeg"
)} : (null)
Has anybody had luck getting custom Transferable representations to work with ShareLink?
I am trying to implement "Live activity" to my app. I am following the Apple docs.
Link: https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities
Example code:
struct LockScreenLiveActivityView: View {
let context: ActivityViewContext<PizzaDeliveryAttributes>
var body: some View {
VStack {
Spacer()
Text("\(context.state.driverName) is on their way with your pizza!")
Spacer()
HStack {
Spacer()
Label {
Text("\(context.attributes.numberOfPizzas) Pizzas")
} icon: {
Image(systemName: "bag")
.foregroundColor(.indigo)
}
.font(.title2)
Spacer()
Label {
Text(timerInterval: context.state.deliveryTimer, countsDown: true)
.multilineTextAlignment(.center)
.frame(width: 50)
.monospacedDigit()
} icon: {
Image(systemName: "timer")
.foregroundColor(.indigo)
}
.font(.title2)
Spacer()
}
Spacer()
}
.activitySystemActionForegroundColor(.indigo)
.activityBackgroundTint(.cyan)
}
}
Actually, the code is pretty straightforward. We can use the timerInterval for count-down animation. But when the timer ends, I want to update the Live Activity view. If the user re-opens the app, I can update it, but what happens if the user doesn't open the app? Is there a way to update the live activity without using push notifications?
Hi everyone,
I am running into a navigation-related issue that appears to be new in iOS 16/SwiftUI 4. The code below illustrates the problem:
struct ContentView: View {
@State private var input: String = ""
var body: some View {
NavigationStack {
VStack {
Spacer()
NavigationLink("Navigate") {
Text("Nested View")
}
Spacer()
TextEditor(text: $input)
.border(.red)
.frame(height: 40)
}
.padding()
}
}
}
The initial view consists of a navigation link and a text editor at the bottom of the screen. I run the app on an iPhone (or the simulator) in iOS 16 and click on the text editor at the bottom of the screen. This invokes the virtual keyboard, which pushes up the text field. Next, I click on "Navigate" to navigate to the nested view. I navigate immediately back, which brings back the initial view without the keyboard. Unfortunately, the text field isn't pushed back to the bottom and is now located in the middle of the screen. (see attached image)
Did anyone experience similar issues? Is there a workaround I could use to force a re-layout of the initial view upon return from the navigation link?
Thanks,
Matthias
I have a small text file which I would like to share via ShareLink with watchOS. If I try to share the text file via Mail oder iMessage the recipient only receives the message without the attachment. The same code works without problems on iOS. Is the is watchOS bug?
I tried the example from https://developer.apple.com/documentation/swiftui/editmode. It's not working for me.
struct ContentView: View {
@Environment(\.editMode)
private var editMode
@State
private var name = "Maria Ruiz"
var body: some View {
NavigationView {
Form {
Text(String(editMode!.wrappedValue.isEditing))
if editMode?.wrappedValue.isEditing == true {
TextField("Name", text: $name)
} else {
Text("test")
}
}
.animation(nil, value: editMode?.wrappedValue)
.toolbar { // Assumes embedding this view in a NavigationView.
EditButton()
}
}
}
}
It shows the texts "false" and "test", before and after clicking Edit. What am I missing? I'm using XCode 14.0.1 and the deployment target is iOS 16. I also tried on a real iPhone and on iOS 15.5 in the Simulator. Thanks for any help.
Is there a way to implement controls for background audio using ActivityKit like in the Apple Music application? I didn't found anything in your documentation about handling actions like this except deep links, but they're not suitable for this use case
In the sidebar column of the NavigationSplitView I'd like to have several sections. All the items are fetched with Core Data.
View all photos (Photos entity in Core Data)
Folder (Folder entity in Core Data)
Folder A
Folder B
Folder C
Tags (Tag entity in Core Data)
Cat
Dog
In the content view, I'd like show the items based on the selection in the sidebar. I tried the following with some success but I think there should be another way of doing this.
NavigationSplitView() {
List(selection: $navigationModel.selectedCategory, content: {
NavigationLink(value: Category(type: .all, predicate: NSPredicate(value: true), title: "View all items") ) {
Text("View all items")
}
Section {
ForEach(folders){ folder in
NavigationLink(value: Category(type: .folder, predicate: NSPredicate(format: "folder == %@", folder), title: folder.name) ) {
FolderRow(folder: folder)
// ... and so on. Another section for tags
And in the content:
ZStack{
List(selection: $navigationModel.selectedPhoto) {
ContentView(photos: FetchRequest(
sortDescriptors: [sortDescriptor],
predicate: navigationModel.selectedCategory?.predicate,
animation: .default)
//....
How can refractor this code with a better solution? The problem that I'm encountering is that the selection argument in the List accepts only one type of object. But I want to select more that one type of object. Another issue is that this solution won't conform to Codable if I'm thinking correctly and reseting the app state on the next launch would be cumbersome.
So I have the default language of my app as Arabic so everything goes from RTL but when I changed the default language to Arabic I started encountering this issue that happens when navigating from one view to another view.
This issue shows the text inverted in a weird way.
here is the image: https://imgur.com/amI8afA
(note that this issue goes away if the TabView is not PageTabViewStyle)
Isn't there no way to set the default filename to use when we want to save a DataRepresentation to a file?
If I export to JSON, the filename is "JSON.json" is used by iOS, even if I set the name to use in SharePreview.
struct ContentView: View {
let car = Car(id: UUID(), name: "911", items:
[Item(id: UUID(),date: .now, desc: "oil change"),
Item(id: UUID(),date: .now, desc: "Battery")])
var body: some View {
VStack {
ShareLink(item: car, preview: SharePreview(car.name))
}
.padding()
}
}
extension UTType {
static var car: UTType = UTType(exportedAs: "com.acme.cararchive")
}
struct Car: Codable {
let id: UUID
let name: String
let items: [Item]
}
extension Car: Transferable {
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(contentType: .json) { archive in
try JSONEncoder().encode(archive)
} importing: { data in
try JSONDecoder().decode(Car.self, from: data)
}
}
}
struct Item: Codable {
let id: UUID
let date: Date
let desc: String
}
So I'm trying to use MapKit in a SwiftUI project targeting iOS/iPadOS. MapKit is obviously pretty limited in SwiftUI, but I've been getting warnings trying to set up basic annotations for the user to interact with.
When I use a basic MapMarker everything is fine (although it's hard to do anything with it), but whenever I do anything with MapAnnotation, I get this warning in Xcode (14.0.1) whenever I move the map around:
[SwiftUI] Publishing changes from within view updates is not allowed, this will cause undefined behavior.
I'm no SwiftUI expert, and I get how to fix this issue when binding in something like a sheet, but I don't see how what I'm doing with MapAnnotation should be causing this.
It looks like a bug to me, possibly complaining about the $region binding, but maybe I'm wrong? Am I doing something wrong or is this a bug?
Below is some sample code that reproduces this easily for me (just launch an app with the below code and then drag the map around to see the constant warnings in Xcode). It's mostly an example from here: https://www.hackingwithswift.com/books/ios-swiftui/integrating-mapkit-with-swiftui
import SwiftUI
import MapKit
struct Location: Identifiable {
let id = UUID()
let name: String
let coordinate: CLLocationCoordinate2D
}
struct ContentView: View {
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.5, longitude: -0.12), span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
let locations = [
Location(name: "Buckingham Palace", coordinate: CLLocationCoordinate2D(latitude: 51.501, longitude: -0.141)),
Location(name: "Tower of London", coordinate: CLLocationCoordinate2D(latitude: 51.508, longitude: -0.076))
]
var body: some View {
Map(coordinateRegion: $region, annotationItems: locations) { location in
MapAnnotation(coordinate: location.coordinate) {
Circle()
.stroke(.red, lineWidth: 3)
.frame(width: 44, height: 44)
}
}
.navigationTitle("Map")
.edgesIgnoringSafeArea(.all)
}
}
I have a class that I cannot change to ObservableObject with Published members.
I tried getting around this by writing my own Binding. Although the value is updated correctly, the UI is not. Why is this.
Below is a simple demo view. When it is run and the toggle is clicked, it will print out correctly that the value is changed, but the UI does not update. Why?
import SwiftUI
class BoolWrapper {
public var value = false {
didSet {
print("Value changed to \(value)")
}
}
}
let boolWrapper = BoolWrapper()
struct ContentView: View {
var body: some View {
Toggle(isOn: Binding(get: {
return boolWrapper.value
}, set: { value in
boolWrapper.value = value
}), label: { Text("Toggle") })
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
while resizing screen on mac, start getting this weird error
[API] cannot add handler to 3 from 3 - dropping
All lazyVgrids fail to show afterwards then app crashes if you keep resizing.
This error started with macOS Ventura.
Any help much appreciated.
Hello all,
In a SwiftUI List, when a row is selected, a blue selection is drawn in the selection, and foreground Text with the default primary color is automatically made white. For other views with custom colors, I'd like to be able to make sure they become tinted white to match the system apps. For example, see the blue dot on the selected row:
Example code:
List(selection: $selection) {
ForEach(0..<4) { index in
HStack {
Image(systemName: "circle.fill")
.foregroundColor(.blue)
Text("Test")
}
.tag(index)
}
}
With NSTableCellView, there is the backgroundStyle property. I've searched all of the available environment variables, and couldn't find anything appropriate. I have also tried manually including an isSelected binding on a view for each row, but the selection binding is not updated by List until mouse-up, while the highlight is updated on mouse-down and drag, so this results in a flickery appearance and is not right either.
Any tips on how to achieve the correct result here? Thanks! 🙏
Xcode 14.1
Running on iPhone 14 Pro max simulator 16.1
Code...
import SwiftUI
struct ContentView: View {
@State var loggedIn: Bool = false
var body: some View {
switch loggedIn {
case false:
Button("Login") {
loggedIn = true
}
.onAppear {
print("🍏 Login on appear")
}
.onDisappear {
print("🍎 Login on disappear")
}
case true:
TabView {
NavigationView {
Text("Home")
.navigationBarTitle("Home")
.onAppear {
print("🍏 Home on appear")
}
.onDisappear {
print("🍎 Home on disappear")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Logout") {
loggedIn = false
}
}
}
}
.tabItem {
Image(systemName: "house")
Text("Home")
}
NavigationView {
Text("Savings")
.navigationBarTitle("Savings")
.onAppear {
print("🍏 Savings on appear")
}
.onDisappear {
print("🍎 Savings on disappear")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Logout") {
loggedIn = false
}
}
}
}
.tabItem {
Image(systemName: "dollarsign.circle")
Text("Savings")
}
NavigationView {
Text("Profile")
.navigationBarTitle("Profile")
.onAppear {
print("🍏 Profile on appear")
}
.onDisappear {
print("🍎 Profile on disappear")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Logout") {
loggedIn = false
}
}
}
}
.tabItem {
Image(systemName: "person")
Text("Profile")
}
}
.onAppear {
print("🍏 Tabview on appear")
}
.onDisappear {
print("🍎 Tabview on disappear")
}
}
}
}
Video of bug... https://youtu.be/oLKjRGL2lX0
Example steps...
Launch app
Tap Login
Tap Savings tab
Tap Home tab
Tap Logout
Expected Logs...
🍏 Login on appear
🍏 Tabview on appear
🍏 Home on appear
🍎 Login on disappear
🍏 Savings on appear
🍎 Home on disappear
🍏 Home on appear
🍎 Savings on disappear
🍏 Login on appear
🍎 Home on disappear
🍎 Tabview on disappear
Actual logs...
🍏 Login on appear
🍏 Tabview on appear
🍏 Home on appear
🍎 Login on disappear
🍏 Savings on appear
🍎 Home on disappear
🍏 Home on appear
🍎 Savings on disappear
🍏 Login on appear
🍏 Savings on appear
🍎 Home on disappear
🍎 Savings on disappear
🍎 Tabview on disappear
Error...
10 and 12 in the actual logs should not be there at all.
For each tab that you have visited (that is not the current tab) it will call onAppear and onDisappear for it when the tab view is removed.
I'm using Xcode 14.1 to start a Core Data project. I created a new Project, checking CoreData. The resulting program works in Preview and in the Simulator.
I've changed the data from a Item/timestamp to Locations/title. I plan to add more Attributes but that's for later.
I think I've got all the Item instances changed to Locations and timestamp to title. It seems to work OK when in Preview for ContentView.swift but crashes in the Simulator with the error
Swift/UnsafeRawBufferPointer.swift:946: Fatal error: UnsafeRawBufferPointer with negative count
Any suggestions on what I have done wrong? Thanks.
PS, the New Project includes the line Text("Select a location") but Select a location doesn't appear in the Preview.