Post not yet marked as solved
It looks like passing a binding (instead of value) to a detail view is not possible with NavigationSplitView.
For example, how to adopt NavigationSplitView in sample app Date Planner — Sample Apps Tutorials | Apple Developer Documentation does not seem straight forward.
The only way seems to be to use ObservableObjects and use separate update methods on data.
...
ForEach(eventData.sortedEvents(period: period)) { $event in
NavigationLink {
EventEditor(event: $event)
} label: {
EventRow(event: event)
}
Post not yet marked as solved
I'm using TABLE in SwiftUI macOS app with several Table Columns: each column has an associated sort key. The sorting works fine but my question is:
If the table supports single row selection, is there a way to scroll to the selected row after a sort operation? EG if I have 300 rows and only 50 display at a time if row 5 is selected and column sorting moves this row to row 200 how can I scroll to row 200 after sort?
I have seen examples of using LIST and ScrollViewReader to programmatically scroll to a LIST row but this approach does not appear to work with TABLE structures.
Post not yet marked as solved
In a SwiftUI document based application on macOS, you often see the following scenario: the user closes an application in which several documents have been opened, and the next time he starts the application, he expects that the state of the application will remain and all these documents will also be open.
After studying the SwiftUI documentation, I have not found a way to automatically open previous documents, nor is it clear whether the dimensions of the application/document window can be saved so that they apply when it is opened at a later time.
I assume SwiftUI has a mechanism to do this, since xCode opens the application after an interruption completely preserving its previous state. So I suspect it's a trivial question, I'm just looking in the wrong place, any help would be appreciated.
Post not yet marked as solved
Hi! I am trying to make a maze game, and right now I am simply working on generating the maze. I have code that randomizes the contents of an array called "right". This array has enough members to fill what the maze size is, but when I run my code, the views don't update, the ForEach function seems to make it so it cannot read data from my DataBase. Please help me?
import SwiftUI
struct ContentView: View {
@StateObject var data: DataBase
@StateObject var trafficControl: TrafficControl
var body: some View {
ZStack{
Group{
LazyVStack{
ForEach(1...data.size, id: \.self) { index in
LazyHStack {
ForEach(1...data.size, id: \.self) { box in
Rectangle().fill(Color.gray).frame(width: 90, height: 90, alignment: .center).scaledToFill().padding(-4)
}
}
}
}
LazyVStack{
ForEach(1...(data.size), id: \.self) { index in
LazyHStack {
ForEach(1...(data.size + 1), id: \.self) { box in
if data.**** == 1 {
Rectangle().fill(Color.gray).frame(width: 6, height: 90, alignment: .center).scaledToFill().padding(.trailing, 38).padding(.leading, 38).padding(.top, -4).padding(.bottom, -4)
}
else {
Rectangle().fill(Color.black).frame(width: 6, height: 90, alignment: .center).scaledToFill().padding(.trailing, 38).padding(.leading, 38).padding(.top, -4).padding(.bottom, -4)
}
}
}
}
}
LazyHStack{
ForEach(1...data.size, id: \.self) { index in
LazyVStack {
ForEach(1...(data.size + 1), id: \.self) { box in
Rectangle().fill(
Color.black).frame(width: 90, height: 6, alignment: .center).scaledToFill().padding(.top, 38).padding(.bottom, 38).padding(.trailing, -4).padding(.leading, -4)
}
}
}
}
Rectangle().fill(Color.white).frame(width: 60, height: 60, alignment: .center).scaledToFill()
}.offset(x: CGFloat(data.ex), y: CGFloat(data.why)).onAppear(){
print("\(data.size/2 + 1)")
}
Circle().fill(Color.black).frame(width: 20, height: 20, alignment: .center).scaledToFill()
}.gesture(DragGesture(minimumDistance: 40)
.onEnded { endedGesture in
if (endedGesture.location.x - endedGesture.startLocation.x) > 0 {
if (endedGesture.location.y - endedGesture.startLocation.y) > (endedGesture.location.x - endedGesture.startLocation.x) {
data.why -= 90
}
else if (endedGesture.startLocation.y - endedGesture.location.y) > (endedGesture.location.x - endedGesture.startLocation.x) {
data.why += 90
}
else {
data.ex -= 90
}
}
else if (endedGesture.startLocation.x - endedGesture.location.x) > 0 {
if (endedGesture.location.y - endedGesture.startLocation.y) > (endedGesture.startLocation.x - endedGesture.location.x) {
data.why -= 90
}
else if (endedGesture.startLocation.y - endedGesture.location.y) > (endedGesture.startLocation.x - endedGesture.location.x) {
data.why += 90
}
else {
data.ex += 90
}
}
else if (endedGesture.startLocation.y - endedGesture.location.y) > (endedGesture.location.y - endedGesture.startLocation.y) {
data.why += 90
}
else {
data.why -= 90
}
data.corx = data.ex/90
data.cory = data.why/90
}
)}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(data: DataBase(), trafficControl: TrafficControl())
}
}
Post not yet marked as solved
I am using bottom sheet for my app, and it is work correctly, but I want to use the half bottom sheet, is it possible?
Image( "color")
.resizable()
.frame(width:45, height: 45)
.sheet(isPresented: $showSheet, content: {
ScreenView()
})
Post not yet marked as solved
Is there any convenient way to back deploy the NavigationStack or NavigationSplitView??
The real problem is if I want to back support iOS 15 or 14, I must conditionally switch between NavigationView and NavigationStack / NavigationSplitView.
Here is how I did for NavigationStack, but I have no idea how to deal with NavigationSplitView
import SwiftUI
struct NavigationStack<Content: View>: View {
var content: () -> Content
var body: some View {
if #available(iOS 16.0, macOS 13.0, *) {
SwiftUI.NavigationStack {
content()
}
} else {
NavigationView {
content()
}.navigationViewStyle(.stack)
}
}
}
Will the new NavigationStack and NavigationSplitView back support old devices? I think these behaviors in previous OS is not new features.
Hi Team,
I have been trying to display the difference between two dates in integer numbers only. This code works in SwiftUI playground. But in the SwiftUI ContentView it gives me an error. I have copied both sets of code below. Any suggestions?
//Swift Playground Code starts here:
let theFirstDate = Date(timeIntervalSince1970: 5)
let theSecondDate = Date()
let theComponents = Calendar.current.dateComponents([.month], from: theFirstDate, to: theSecondDate)
let theNumberOfMonth = theComponents.month
let Months = theNumberOfMonth
//Swift Playground Code ends here
// This code works perfectly
// Displays the result as
"Dec 31, 1969 at 6:00 PM"
"Jul 15, 2022 at 6:05 PM"
month: 630 isLeapMonth: false
630
630
I am looking to display the number 630 in the SwiftUI code below,
// SwiftUI Code starts here
import SwiftUI
struct ContentView: View {
@State var PurchaseDate = Date.now
@State var Months: Int = 0
// Date picker. Here I select a date
var body: some View {
VStack(alignment: .leading){
DatePicker("Date of Purchase", selection: $PurchaseDate, in: ...Date(), displayedComponents: .date)
Spacer()
// Here we assign today's date
let date = Date()
let dateDiff = Calendar.current.dateComponents([.month], from: PurchaseDate, to: date)
let Months = dateDiff.month
// In the next line of code, I want to display months in integer, but I get the error
Text("$(Months)") // On this line display error message is "No exact matches in call to instance method 'appendInterpolation'"
Spacer()
}
}
}
simply trying to define a published variable of type CGFloat...import Combineimport Foundationclass Percentage:ObservableObject {@Published var percentage : CGFloat = 0}yields the error: Use of undeclared type 'CGFloat'YAAAAA! another basic error that should NEVER occurwhat a piece of junk.Long gone are the days of Steve Jobs and quality products that worked with apple.Now, it's problem after problem, error after error.The people at apple need to get back to basics, and build quality products that work.They need a hard lesson in TIME IS MONEY! I don't have the money or the time to fight with editors or basic things that should just work!
Post not yet marked as solved
Hello,
On the recent iOS / iPadOS 16, SwiftUI 4, and Xcode Version 14.0 beta (14A5228q), my app contains a NavigationStack within the content view; and the stack contains a ForEach that iterates over a list of fruits / items. The form loop outputs a navigation link, the label being a view, and the destination being another NavigationStack. And whenever I go to click on that link, the app shoots me back to the root view instantly. This seems to happen whenever I have any kind of content in the StackNavigation that's within the NavigationLink. I will post the code snippets below, along with a GIF showing the bug in action.
ContentView.Swift:
struct ContentView: View {
@State private var isShowingSettings: Bool = false
var fruits: [Fruit] = fruitsData
var body: some View {
NavigationStack {
List(fruits.shuffled()) { fruit in
NavigationLink(destination: FruitDetailView(fruit: fruit)) {
FruitRowView(fruit: fruit)
.padding(.vertical, 4)
}
}
.navigationBarTitle("Fruits")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
isShowingSettings = true
}) {
Image(systemName: "slider.horizontal.3")
}
.sheet(isPresented: $isShowingSettings) {
SettingsView()
}
}
}
}
}
}
FruitDetailView.Swift:
// Code is shortened, but has the same bug as the actual code
struct FruitDetailView: View {
var fruit: Fruit
var body: some View {
NavigationStack {
ScrollView(.vertical, showsIndicators: false) {
Text(fruit.name)
}
.edgesIgnoringSafeArea(.top)
}
}
Preview:
Post not yet marked as solved
Restoring a NavigationStack path (NavigationPath) from a codable representation, crashes the app with the following error:
Failed to decode item in navigation path at index 0. Perhaps the navigationDestination declarations have changed since the path was encoded?
Fatal error: throw through?
Note that the error is thrown when the view appears, not when the NavigationPath(representation) is initialized.
In this example, navigation declarations have not changed and restoration should succeed. However, even there was an error restoring the path, this should not be a fatal error. It should be handled gracefully. Consider a new app version being distributed where the destinations did changed. The stack restoration should fail and navigate to the root, but not crash.
Problem occurs both in iOS 16 beta 3 and macOS 13 beta 3.
struct Movie: Identifiable, Hashable, Codable {
let id: Int
let name: String
let year: Int
}
struct TVShow: Identifiable, Hashable, Codable {
let id: Int
let name: String
let episodes: Int
}
class Model: ObservableObject {
let movies = [
Movie(id: 1, name: "Blade Runner", year: 1982),
Movie(id: 2, name: "Back to the Future", year: 1985),
Movie(id: 3, name: "Mission Impossible", year: 1996),
]
let shows = [
TVShow(id: 1, name: "Cheers", episodes: 275),
TVShow(id: 2, name: "Taxi", episodes: 114)
]
@Published var path: NavigationPath
init() {
if let data = UserDefaults.standard.object(forKey: "path") as? Data {
do {
let representation = try JSONDecoder().decode(NavigationPath.CodableRepresentation.self, from: data)
self.path = NavigationPath(representation)
} catch {
print("Unable to decode path \(error)")
self.path = NavigationPath()
}
} else {
self.path = NavigationPath()
}
}
func save() {
guard let representation = path.codable else { return }
do {
let encoder = JSONEncoder()
let data = try encoder.encode(representation)
UserDefaults.standard.set(data, forKey: "path")
} catch {
print("Unable to encode path \(error)")
}
}
}
struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
@StateObject var model = Model()
var body: some View {
NavigationStack(path: $model.path)
{
List {
Section("Movies") {
ForEach(model.movies) { movie in
NavigationLink(movie.name, value: movie)
}
}
Section("TV Shows") {
ForEach(model.shows) { show in
NavigationLink(show.name, value: show)
}
}
}
.navigationDestination(for: Movie.self, destination: { MovieView(movie: $0) })
.navigationDestination(for: TVShow.self, destination: { TVShowView(show: $0) })
}
.onChange(of: scenePhase) { phase in
if phase == .background {
model.save()
}
}
}
}
struct MovieView: View {
let movie: Movie
var body: some View {
Form {
LabeledContent("Title", value: movie.name)
LabeledContent("Year" , value: "\(movie.year)")
}
}
}
struct TVShowView: View {
let show: TVShow
var body: some View {
Form {
LabeledContent("Title", value: show.name)
LabeledContent("Episodes" , value: "\(show.episodes)")
}
}
}
Post not yet marked as solved
I'm currently trying to save a selected image in core data as a type data, but I'm getting an error in the persistence file marked with a comment. I've included my code and any questions I will gladly answer. Thanks for any help!
Content View:
import SwiftUI
import PhotosUI
struct ContentView: View {
@ObservedObject var persistence = PersistenceController.shared
@State var selectedItems: [PhotosPickerItem] = []
@State var data: Data?
var body: some View {
NavigationView{
VStack{
Spacer()
VStack{
Spacer()
if let data = data, let uiimage = UIImage(data: data) {
Image(uiImage: uiimage)
.resizable()
.scaledToFit()
.frame(width: 250, height: 500)
}
Spacer()
}
Spacer()
PhotosPicker(selection: $selectedItems, maxSelectionCount: 1, matching: .images){
Text("Pick Photo")
}
.onChange(of: selectedItems){ newValue in
guard let item = selectedItems.first else{
return
}
item.loadTransferable(type: Data.self){ result in
switch result {
case .success(let data):
if let data = data{
self.data = data
} else {
print("Data is nil")
}
case .failure(let failure):
fatalError("\(failure)")
}
}
}
Spacer()
}
.navigationBarItems(trailing: addButton)
}
}
var addButton: some View {
Button(action: {
guard let item = selectedItems.first else{
return
}
item.loadTransferable(type: Data.self){ result in
switch result {
case .success(let data):
if let data = data{
persistence.addObject(image: data)
} else {
print("Data is nil")
}
case .failure(let failure):
fatalError("\(failure)")
}
}
}){
Text("Add Image").bold()
}
}
}
Persistence:
import Foundation
import CoreData
class PersistenceController: ObservableObject {
static let shared = PersistenceController()
let container: NSPersistentContainer
init(inMemory: Bool = false) {
container = NSPersistentContainer(name: "ReciPlanner")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
func addObject(image: Data){
let context = container.viewContext
let object = Object(context: context) //Error: Thread 7: "An NSManagedObject of class 'Object' must have a valid NSEntityDescription."
object.item = image
}
func contextSave() {
let context = container.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
print("**** ERROR: Unable to save context \(error)")
}
}
}
}
Data Model:
Post not yet marked as solved
How do I make a SwiftUI view fullscreen running Mac OS, Catalina or Big Sur?
Hello! I'm working with the UIHostingConfiguration and would like to set a Toolbar for a TextField which I placed in the content. I've tried to set ToolbarRole and Toolbar Visibility. Unfortunately, it doesn't work. Here's my example code:
Cell:
cell.configurationUpdateHandler = { (cell, state) in
cell.contentConfiguration = UIHostingConfiguration {
RowView(item: item)
}
}
View:
@ObservedObject var item: Movie
var body: some View {
TextField("Title", text: $item.title)
.toolbar(content: {
ToolbarItem(placement: .keyboard) {
Button("Confirm", action: {})
}
})
.toolbar(.visible, in: .automatic)
}
}
Hi all,
I want to create an application with SwiftUI that either
Quits when the last window is closed, or
Allows one window only. That is, the New Window command is greyed out when a window is already open. I don't hold much hope for this one, not in pure swiftUI, because the commands builder doesn't allow logic.
I am pretty sure this used to be a simple configuration on the Mac, this would be my best hope.
Post not yet marked as solved
Hello,
I just wanted to confirm that ScrollView and prefersDefaultFocus are currently not compatible, at least when building for tvOS
A simple example:
HStack {
ScrollViewReader { proxy in
ScrollView(.horizontal, showsIndicators: true) {
VStack {
Button(action: {
resetFocus(in: namespace)
}) {
Text("RESET FOCUS")
}
HStack {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], id: \.self) { v in
Button(action: {}) {
Text("ABC \(v)")
}.prefersDefaultFocus(v == 11, in: namespace)
}
}
}.onAppear {
resetFocus(in: namespace)
}
}
}
.focusScope(namespace)
}
}
On load of the view the focus remains on the first button in the HStack. On pressing the RESET FOCUS button focus is applied to the first button visible on the left side of the screen.
Am I missing something here? Is this the way these pieces of SwiftUI currently interact? e.g. prefersDefaultFocus has no effect inside a ScrollView?
Is there a way to focus a specific item in a ScrollView programmatically?
Thanks.
Post not yet marked as solved
Is it possible to use create a "nonmodal sheet" as described in the Human Interface Guidelines and as seen in apps like Maps using SwiftUI's .sheet and the new .presentationDetents modifier in iOS 16. By default, the content behind the sheet is not interactive.
Is there a built in modifier or modality style that can be applied to the sheet to allow for interactive content behind the sheet?
Post not yet marked as solved
How can I add a native UX for pull-to-refresh for a ScrollView? Is support for this being added in iOS 16? Right now, the native UX only appears for List.
For example, I want to support to be able to support .refreshable on a ScrollView like this:
var body: some View {
ScrollView {
LazyVStack {
Text("1")
Text("2")
Text("3")
}
}
.refreshable {
///
}
}
Post not yet marked as solved
I'm trying to use a different version of view modifier when a view is inserted and when its being removed. However combining .asymmetric and .modifier transitions don't quite work as expected.
Here's a test that attempts to print out the combination of states the view transitions between:
struct TransitionPrinting: ViewModifier {
var isInsertion: Bool
var isActive: Bool
func body(content: Content) -> some View {
content
.onAppear {
print("isInsertion", isInsertion, "isActive", isActive)
}
}
}
struct ContentView: View {
@State var toggled = false
var body: some View {
VStack {
Toggle("Toggle", isOn: $toggled)
if toggled {
Text("Hello, world!")
.transition(
.asymmetric(
insertion: .modifier(
active: TransitionPrinting(isInsertion: true, isActive: true),
identity: TransitionPrinting(isInsertion: true, isActive: false)
),
removal: .modifier(
active: TransitionPrinting(isInsertion: false, isActive: true),
identity: TransitionPrinting(isInsertion: false, isActive: false)
)
)
)
}
Spacer()
}
.padding()
}
}
When the above is run, I only see the following in the simulator (with 2 of the states missing):
isInsertion true isActive true
isInsertion false isActive false
What's wrong here?
Post not yet marked as solved
“The best way to build an app is with Swift and SwiftUl.”
But…
Most companies can’t move development to iOS 14/15 and again with iOS 16 we have to wait another year for some basic features:
Allow (or block) device orientations (portrait / landscape) by View
Pull-down to refresh for ScrollView
Custom controls for VideoView
MapView custom view for user location, map configurations and other options
UICalendarView
More ScrollView features (events, zoom, offset control, …)
Many of these features can be implemented ASAP. How complicate is to implement map configurations? How many years we have to wait?
Developers needs more from your team. Thank you!
Post not yet marked as solved
I just noticed, that iOS 16 is using the accent color for the navigation bar back button. (SwiftUI) When running my app on iOS 15 devices it's white.
Is there a way to change that behavior? I want to have another accent color than white.