Hi! I find this code does not work as expected on iOS 17 simulator and device. It was working correctly with iOS 16:
struct ContentView: View {
@State private var numberText = ""
var color: Color {
let result = (Int(numberText) ?? 0) <= 0
if result {
return .black
}
return .red
}
var body: some View {
VStack {
TextField("Enter a number", text: $numberText)
.font(.title)
.foregroundStyle(
color
)
Text("Font color will turn red if number > 0")
.foregroundColor(.gray)
}
.padding()
}
}
I tried a workaround and it works:
struct ContentView: View {
@State private var numberText = ""
@State private var color = Color.black
func updateColor() ->Color {
let result = (Int(numberText) ?? 0) <= 0
if result {
return .black
}
return .red
}
var body: some View {
VStack {
TextField("Enter a number", text: $numberText)
.font(.title)
.foregroundStyle(
color
)
.onChange(of:numberText) {
color = updateColor()
}
Text("Font color will turn red if number > 0")
.foregroundColor(.gray)
}
.padding()
}
}
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Before visionOS Beta 4 it was possible to define the launch size in the Info.plist using PreferredLaunchSize like so:
<key>UILaunchPlacementParameters</key>
<dict>
<key>PreferredLaunchSize</key>
<dict>
<key>Height</key>
<integer>750</integer>
<key>Width</key>
<integer>750</integer>
</dict>
</dict>
In visionOS Beta 4 this now doesn't work anymore and the window opens in a 16:9 format and then will scale down to the .defaultSize of the WindowGroup with an animation.
Settings, Notes, Safari still open with a different default size though, including the launch screen.
How are we supposed to do this now?
I want to recreate an user experience like in the settings app in tvOS. Therefore I have a HStack with some content on the left side and a List of NavigationLinks on the right side.
However a focused link in the list gets clipped on the left side. I tried paddings and spacers and what not, but nothing helped. Is this is a bug or am I missing something?
Here is some example code to show the problem:
struct ContentView: View {
var body: some View {
NavigationStack {
HStack(spacing: 20) {
VStack(alignment: .center) {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
List {
ForEach(SomeViewEnum.allCases) { someView in
NavigationLink(someView.rawValue, value: someView)
}
}
.navigationDestination(for: SomeViewEnum.self) { someView in
Text(someView.rawValue)
}
}
}
}
}
And a screenshot to show the problem:
After upgrading to iOS 17 I am struggling to get decimals working in my app - here is a sample code: for clarity I provide a complete "working" sample (I am pulling data from a back-end server using json, etc - all of that is working ok, it's the UI issue - see below):
Model
import Foundation
struct TestFloat: Encodable {
var testFloatNumber: Float = 0
}
Observable Class
import Foundation
class TestFloatViewModel: ObservableObject {
@Published var testFloat = TestFloat()
}
View
struct TestFloatView: View {
@ObservedObject var testFloatVM: TestFloatViewModel
let formatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter
}()
var body: some View {
VStack {
HStack {
Text("Enter Float Number")
Spacer()
}
Spacer()
.frame(height: 2.0)
HStack {
TextField("Enter Float Number", value: $testFloatVM.testFloat.testFloatNumber, formatter: formatter)
.keyboardType(.decimalPad)
.textFieldStyle(.roundedBorder)
}
}
}
}
This is working on a device with iOS16; however when run on device with iOS17:
you can enter maximum four digits?
using backspace you can delete all numbers apart of the first one
you cannot enter the decimal (.) at all even though decimal keyboard is provided
Any help is greatly appreciated.
I'm working on a NavigationStack based app. Somewhere I'm using:
@Environment(\.dismiss) private var dismiss
and when trying to navigate to that view it gets stuck.
I used Self._printChanges() and discovered the environment variable dismiss is changing repeatedly. Obviously I am not changing that variable explicitly. I wasn't able to reproduce this in a small project so far, but does anybody have any idea what kind of thing I could be doing that might be causing this issue?
iOS 17.0.3
I am using public struct ShareLink<Data, PreviewImage, PreviewIcon, Label> : View where Data : RandomAccessCollection, PreviewImage : Transferable, PreviewIcon : Transferable, Label : View, Data.Element : Transferable {}
And it is generating entitlement errors and not working reliably ( will transfer 1-3 items, but not 4+ ; will not work a second time)
Error is:
Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)" UserInfo={NSLocalizedFailureReason=(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)}>
Received port for identifier response: <> with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false}
elapsedCPUTimeForFrontBoard couldn't generate a task port
Received port for identifier response: <> with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false}
elapsedCPUTimeForFrontBoard couldn't generate a task port
Received port for identifier response: <> with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false}
Code is
import SwiftUI
var images = Array<Image?>(repeating: nil , count: 200);
struct ShareTestGContentView: View {
let columns = [GridItem(.fixed(165)), GridItem(.fixed(165))]
private let twoColumnGrid = [ GridItem(.flexible(minimum: 40), spacing: 2), GridItem(.flexible(minimum: 40), spacing: 2) ]
@State var selected = Set()
var body: some View {
topSection()
ScrollView {
LazyVGrid(columns: twoColumnGrid, spacing: 2) { // columns: [GridItem(.flexible())]) {
ForEach(1...100, id: \.self) { idx in
var cr = ( selected.contains(idx) ? 16.0 : 0 )
var lw = ( selected.contains(idx) ? 8.0 : 0 )
VStack{
Button(action: {
if selected.contains(idx) {
selected.remove(idx); cr = 0.0; lw = 0.0
} else {
selected.insert(idx); cr = 16.0; lw = 8.0
}
} , label: {
AsyncImage(url :URL(string: "https://picsum.photos/800/800?\(idx)")) { image in
let _ = ( images[idx] = image.image )
image.image
}.frame(width: boxHalf,height:boxHalf).drawingGroup()
})
}.overlay(
RoundedRectangle(cornerRadius: cr).stroke(Color.yellow, lineWidth: lw)
).drawingGroup()
}
}
}
}
func topSection() -> some View {
let imgarray = selected.compactMap { images[$0] }
return HStack {
ShareLink("",items: imgarray) { img in
SharePreview("images", image: Image(systemName: "captions.bubble.fill"))
}
}
}
}
#Preview {
ShareTestGContentView()
}
Hello all, I am playing with MapKit for SwiftUI, so far so good. There is one thing I have not seen any documentations, or sample codes around and that's elevation data, e.g.
My questions are:
Is there a way to get this information from an MKRoute?
Is it possible to get the elevation gain/drop at a given point in the route?
Many thank in advance for your help.
I try to change picker text color but, it does not work.
As you see, "City" and "District"'s color are blue but, I'd like to make them white. I have tried below codes but, they do not work.
Do you know any methods for that ?
Picker("İl", selection: $selectedCity) {
ForEach(turkishCities, id: \.self) { city in
Text(city)
.foregroundColor(.white)
}
}
Picker("İlçe", selection: $selectedDistrict) {
ForEach(cityDistricts[selectedCity] ?? [], id: \.self) { district in
Text(district)
.foregroundColor(Color.white)
}
}
.onAppear {
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white], for: .normal)
}
Thank you in advance.
According to docs, .focusedObject() usage should be moved to .focusedValue() when migrating to @Observable, but there is no .focusedSceneValue() overload that accepts Observable like with .focusedValue(). So how are we supposed migrate .focusedSceneObject() to @Observable?
I'm currently evaluating Swift Charts to use in my macOS app, where I need to (potentially) display a few millions of data points, ideally all of them at one time. I want to give users the possibility to zoom in & out, so the entire range of values could be displayed at one moment.
However, starting at around 20K data points (on my computer), the Chart takes a little bit to set up, but the window resizing is laggy. The performance seems to decrease linearly (?), when dealing with 100K data points you can barely resize the window and the Chart setup/creation is noticeable enough. Dealing with 500K data points is out of the question, the app is pretty much not useable.
So I'm wondering if anybody else had a similar issue and what can be done? Is there any "magic" Swift Charts setting that could improve the performance? I have a "data decimation" algorithm, and given no choice I will use it, but somehow I was hoping for Swift Charts to gracefully handle at least 100K data points (there are other libs which do this!). Also, limiting the displayed data range is out of the question for my case, this is a crucial feature of the app.
Here's the code that I'm using, but it's the most basic one:
struct DataPoint: Identifiable {
var id: Double { Double(xValue) }
let xValue: Int
let yValue: Double
}
let dataPoints: [DataPoint] = (0..<100_000).map { DataPoint(xValue: $0, yValue: Double($0)) }
struct MyChart: View {
var body: some View {
Chart(dataPoints) { dataPoint in
PointMark(x: .value("Index", dataPoint.xValue),
y: .value("Y Value", dataPoint.yValue))
}
}
}
Some additional info, if it helps:
The Chart is included in a AppKit window via NSHostingController (in my sample project the window contains nothing but the chart)
The computer is a MacBook Pro, 2019 and is running macOS 10.14
I have my ContentView which has a Sheet that will appear when a button is pressed.
struct ContentView: View {
@EnvironmentObject private var settings: SettingsHandler
@State private var settingsView: Bool = false
var body: some View {
NavigationStack {
Button(action: {
settingsView.toggle()
}, label: {
Image(systemName: "gearshape.fill")
})
}
.preferredColorScheme(settings.darkTheme ? .dark : nil)
.sheet(isPresented: $settingsView, content: {
SettingsView()
})
}
}
Let's say the app is in light mode based on the phones theme settings. You open the SettingsView and select the toggle that will switch to dark mode. Everything changes to dark mode, including the SettingsView sheet. Then you select the same toggle to switch back and ContentView in the background changes to light theme but the sheet doesn't until you close and reopen it. I would think it would change back considering it changed to dark mode without needing to be closed.
I tried attaching an ID to the SettingsView and having it refresh when settings.darkTheme is changed, however, it doesn't seem to be doing anything. I also added the .preferredColorScheme() modifier into the SettingsView, but it did nothing. I also replaced the nil to .light, and the same issue occurred. Settings is an EnvironmentObject that I created to manage all the Settings I have.
At the moment, I'm thinking I can have the sheet just close and reopen, however, I would like for it to update properly. Any ideas?
Even if there are one-many relationship models with the cascade delete rule, SwiftData does not cascade delete items.
For example, there is one school has multiple students like the following models, and even when the school is deleted, the students in the school are not deleted. This happens when a user create a school and students and delete the school immediately.
Are there any workarounds for now?
@Model
final class School {
var name: String
@Relationship(deleteRule: .cascade, inverse: \Student.school)
var students: [Student] = []
init(name: String) {
self.name = name
}
}
@Model
final class Student {
var fullName: String
var school: School
init(fullName: String, school: School) {
self.fullName = fullName
self.school = school
}
}
Given that SwiftUI and modern programming idioms promote asynchronous activity, and observing a data model and reacting to changes, I wonder why it's so cumbersome in Swift at this point.
Like many, I have run up against the problem where you perform an asynchronous task (like fetching data from the network) and store the result in a published variable in an observed object. This would appear to be an extremely common scenario at this point, and indeed it's exactly the one posed in question after question you find online about this resulting error:
Publishing changes from background threads is not allowed
Then why is it done? Why aren't the changes simply published on the main thread automatically?
Because it isn't, people suggest a bunch of workarounds, like making the enclosing object a MainActor. This just creates a cascade of errors in my application; but also (and I may not be interpreting the documentation correctly) I don't want the owning object to do everything on the main thread.
So the go-to workaround appears to be wrapping every potentially problematic setting of a variable in a call to DispatchQueue.main. Talk about tedious and error-prone. Not to mention unmaintainable, since I or some future maintainer may be calling a function a level or two or three above where a published variable is actually set. And what if you decide to publish a variable that wasn't before, and now you have to run around checking every potential change to it?
Is this not a mess?
I have an SwiftUI iOS app that uses TabView to display 4 different NavigationStacks. Each stack can be navigated into.
To make this app work better on iPad OS I'd like to use a NavigationSplitView with a sidebar and a detail view. The sidebar contains a menu with the 4 items that are tabs on iOS. The detail view should contain individual NavigationStacks that should retain their view paths.
After having played around with it a bit it seems to me that NavigationSplitView is not meant to be used that way. The detail view resets every time I select another menu item in the sidebar. I've tried retaining the individual navigation paths (as @States) in my root view and passing them into the individual NavigationStack when creating the detail view. However, it seems like NavigationSplitView is resetting the path whenever you switch to another menu item.
Has anybody figured this out?
I've encountered a weird issue with the new Map for iOS 17. In my list, which includes a MapView among other elements, I've observed that with the new initializer, the top and bottom bars are persistently displayed. They don't hide and only appear when scrolling, as they should. This problem doesn't occur with the old, now-deprecated initializer. To illustrate this, I have two screenshots: one with the map enabled and the other with the map disabled, demonstrating the issue.
Here is also my new Map code:
struct MapListRowView: View {
@Binding internal var location: LocationModel
@State internal var user: Bool = true
private var position: CLLocationCoordinate2D { .init(latitude: location.latitude, longitude: location.longitude) }
private var isPad: Bool { UIDevice.current.userInterfaceIdiom == .pad ? true : false }
var body: some View {
Map(bounds: .init(minimumDistance: 1250)) {
if user { UserAnnotation() }
Annotation("", coordinate: position) {
ZStack {
Circle().fill().foregroundColor(.white).padding(1)
Image(systemName: "mappin.circle.fill")
.resizable()
.foregroundColor(.indigo)
}.frame(width: 20, height: 20).opacity(user ? .zero : 1.0)
}
}
.frame(height: isPad ? 200 : 100)
.cornerRadius(8)
.listRowInsets(.init(top: -5, leading: .zero, bottom: -5, trailing: .zero))
.padding(.vertical, 5)
.disabled(true)
}
}
I have something that looks like:
NavigationStack {
List(self.items, id: \.self, selection: self.$selectedItems) { item in
NavigationLink {
ItemView(item: item)
.environment(\.managedObjectContext, self.viewContext)
} label: {
LabelWithMenuView(object: item) { ptr in
self.labelHandler(item: item, newName: ptr)
}
}
}
if self.editMode?.wrappedValue == .active {
editButtons
} else {
TextField("Add Item", text: self.$newItem)
.onSubmit {
self.addItem()
self.newItem = ""
}
.padding()
}
}
#if os(iOS)
.toolbar {
EditButton()
}
.onChange(of: self.editMode?.wrappedValue) { old, new in
print("editMode \(old) -> \(new)")
}
#endif
With that layout, the edit button doesn't show up at all; if I put it as part of the List, it does show up, but the first click doesn't do anything; after that, it works, but the onChange handler doesn't show it getting changed, and the editButtons don't go away.
Platform
Late 2018 Intel 15” MacBook Pro
macOS 15
Xcode 15, CLTools 15
Fault Message
This fault message started after upgrading to macOS Sonoma 15. It only occurs on macOS targeted projects (not iOS). The fault occurs on projects using the TextField or TextEditor views. The projects build, test and run fine.
FAULT: <NSRemoteView: 0x7f7f8ec34fe0 com.apple.TextInputUI.xpc.CursorUIViewService TUICursorUIViewService> determined it was necessary to configure <TUINSWindow: 0x7f7f8e91b490> to support remote view vibrancy
Example
The fault does not occur in UI Tests
ContentView.txt
FaultTestUITests.txt
I have a scroll view that scrolls horizontally and one of my users is asking that it respond to their scroll wheel without them having to use the shift key. Is there some way to do this natively? If not, how can I listen for the scroll wheel events in swiftUI and make my scroll wheel scroll to respond to them?
I recently changed my old ancient MacBookPro for a MBAir 15" M2., mainly to upgrade Xcode and Swift to SwiftUI.
But using Xcode 15.1, trying to update the preview, or trying to run the code I get bombarded by these warnings:
managedappdistributiond unexpectedly quit
findmylocated unexpectedly quit
aegirposter unexpectedly quit.
The warnings are so frequent that it stops me programming.
Mind, I'm not a professional programmer, rather a very driven amateur, but I don't think this this is what is meant by offering a great API.
Can someone please help me get rid off all this irritating stuff.
Trying to use new Swift @Observable to monitor GPS position within SwiftUI content view. But how do I tie the latest locations to the SwiftUI Map's mapCameraPosition?
Well ideally the answer could cover:
How to fix this error - So get map tracking along with the User Position, but also
How to include facility to turn on/off the map moving to track the user position (which I'll need to do next). So could be tracking, then disable, move map around and have a look at things, then click button to start syncing the mapcameraposition to the GPS location again
Refer to error I'm embedded in the code below.
import SwiftUI
import MapKit
@Observable
final class NewLocationManager : NSObject, CLLocationManagerDelegate {
var location: CLLocation? = nil
private let locationManager = CLLocationManager()
func startCurrentLocationUpdates() async throws {
if locationManager.authorizationStatus == .notDetermined {
locationManager.requestWhenInUseAuthorization()
}
for try await locationUpdate in CLLocationUpdate.liveUpdates() {
guard let location = locationUpdate.location else { return }
self.location = location
}
}
}
struct ContentView: View {
var newlocationManager = NewLocationManager()
@State private var cameraPosition: MapCameraPosition = .region(MKCoordinateRegion(
center: newlocationManager.location?.coordinate ?? <#default value#>,
span: MKCoordinateSpan(latitudeDelta: 0.25, longitudeDelta: 0.25)
))
// GET ERROR: Cannot use instance member 'newlocationManager' within property initializer; property initializers run before 'self' is available
var body: some View {
ZStack {
Map(position: $cameraPosition)
Text("New location manager: \(newlocationManager.location?.description ?? "NIL" )") // works
}
.task {
try? await newlocationManager.startCurrentLocationUpdates()
}
}
}
#Preview {
ContentView()
}