You change center before bottom
.alignmentGuide(VerticalAlignment.center) { dim in
dim[.top] // re-assign center to 0
}
.alignmentGuide(VerticalAlignment.top) { dim in
dim[.bottom]
}
.alignmentGuide(VerticalAlignment.bottom) { dim in
dim[VerticalAlignment.center] // 0
}
In order to avoid mutual dependence, center value can not be used when calculating bottom.
.alignmentGuide(VerticalAlignment.bottom) { dim in
dim.height / 2
}
Post
Replies
Boosts
Views
Activity
let publisher = $count
.receive(on: DispatchQueue.main) // receive in the main thread
.map { String(describing: $0) }
.removeDuplicates()
ZStack(alignment: .bottom) {
.....
let isVisible = isVisible // Remove isolation
bottomSheetView
.alignmentGuide(VerticalAlignment.bottom) { dimension in
isVisible ? dimension[.bottom] : dimension[.top]
}
}
or
.alignmentGuide(VerticalAlignment.bottom) { dimension in
_isVisible.wrappedValue ? dimension[.bottom] : dimension[.top]
}
func hide() {
title = ""
message = ""
percentage = 0
withAnimation {
isShowing = false
}
}
https://developer.apple.com/forums/thread/770971?answerId=818590022#818590022
The problem is similar to the one described at https://forums.developer.apple.com/forums/thread/719521, where onAppear is triggered unexpectedly.
The following patterns can currently be summarized:
The navigation container must be within a conditional branch.
The navigation container needs to perform certain operations (such as entering a new navigation page or creating multiple navigation container instances).
Unexpected calls occur when switching to a branch that does not include the navigation container.
This issue occurs only in iOS. I have submitted feedback as well.
Details can be found here: https://fatbobman.com/en/posts/traps-and-countermeasures-for-abnormal-onappear-calls-in-swiftui/
I adjusted the code to the following form to better reflect the problem of onChange in a multi-layer nested navigation hierarchy.
class ViewModel: ObservableObject {
@Published var count = 0
}
struct Root: View {
@StateObject private var viewModel = ViewModel()
var body: some View {
NavigationStack {
SubView(level: 1)
.navigationDestination(for: Int.self) { value in
SubView(level: value)
}
}
.environmentObject(viewModel)
}
}
struct SubView: View {
let level: Int
@EnvironmentObject var viewModel: ViewModel
var body: some View {
VStack {
let _ = print("level \(level) Update: \(viewModel.count)")
Text("Level: \(level)")
Text("Count: \(viewModel.count)")
Button("Count++") {
viewModel.count += 1
}
NavigationLink(value: level + 1) {
Text("Goto New Level")
}
}
.task(id: viewModel.count) {
print("Level \(level) onTaskID: \(viewModel.count)")
}
.onChange(of: viewModel.count){ _ in
print("Level \(level) onChange: \(viewModel.count)")
}
.onReceive(viewModel.$count){ _ in
print("Level \(level) onReceive: \(viewModel.count)")
}
}
}
Clicking "Goto New Level" will add a level, and clicking "Count++" will increase the count value by one
When the navigation exceeds 2 levels, only the bottom and top onChange closures will respond
No matter how many levels of navigation there are, only the top task(id:) will respond
No matter how many levels of navigation there are, onReceive at each level will respond
Not sure if this is intentional or a bug, I will submit a feedback to Apple later
change WritableKeyPath to ReferenceWritableKeyPath
https://fatbobman.com/en/posts/comprehensive-guide-to-mastering-keypath-in-swift/#writablekeypath-vs-referencewritablekeypath
I attempted to create a model by directly accessing the Managed Object Model (MOM), and the code ran successfully. I also completed the migration process. The implementation is somewhat obscure, and I believe Apple's main purpose in providing this migration method for Core Data is to offer a foundational implementation for phased migrations in SwiftData.
guard let momdURL = Bundle.main.url(forResource: "Model", withExtension: "momd") else { fatalError() }
let model1URL = momdURL.appending(component: "Model.mom")
let model2URL = momdURL.appending(component: "Model 2.mom")
guard let model1 = NSManagedObjectModel(contentsOf: model1URL) else { fatalError() }
guard let model2 = NSManagedObjectModel(contentsOf: model2URL) else { fatalError() }
let v1ModelChecksum = model1.versionChecksum
let v1ModelReference = NSManagedObjectModelReference(model: model1, versionChecksum: v1ModelChecksum)
let v2ModelChecksum = model2.versionChecksum
let v2ModelReference = NSManagedObjectModelReference(model: model2, versionChecksum: v2ModelChecksum)
let customStage = NSCustomMigrationStage(
migratingFrom: v1ModelReference,
to: v2ModelReference
)
let migrationManager = NSStagedMigrationManager([customStage])
let description = container.persistentStoreDescriptions.first
description?.setOption(migrationManager, forKey: NSPersistentStoreStagedMigrationManagerOptionKey)
and I have update my topic about staged migration of Core Data.
https://fatbobman.com/en/posts/what-s-new-in-core-data-in-wwdc23
This should be a bug.
By using SwiftDataKit to inspect the information of NSPersistentStoreCoordinator, I found that only the store corresponding to the first configuration is loaded.
// ModelContainer(for: Schema([Item.self,Tag.self]), configurations: [configuration2,configuration1])
let coordinator = context.coordinator
print(coordinator?.persistentStores.count)
// 1
Interestingly, SwiftData creates a separate sqlite file for each configuration.
I suppose this has already been reported to Feedback, and now we can only wait for Apple to resolve this issue.
func query(group: Group) {
let id = group.id
let predicate = #Predicate<Item> { item in
item.group?.id == id // Compiles
}
}
@MarcusAurelius
This method can indeed compile, but when I use similar code to run, the following error message will appear:
Thread 1: Fatal error: Couldn't find \Tag.id on Tag with fields
May I ask if your code can use the above predicate to fetch data?
Thank you for your reply. However, in some cases, I need to prepare some predicates in advance and combine them according to some conditions during the running of the app. This is also the main use of NSCompoundPredicate in this situation. However, in the new Predicate, no similar mechanism is provided. I feel that PredicateExpression may provide a corresponding method, but I haven't found it yet.
@ModelActor
actor CountryModelActor {
init(container: ModelContainer) {
modelContainer = container
let context = ModelContext(container)
modelExecutor = DefaultSerialModelExecutor(modelContext: context)
}
func newItem() {
let item = Item(timestamp: .now, name: "\(Int.random(in: 0...3))")
modelContext.insert(item)
try! modelContext.save()
}
}
Thank you for your reply.
I have submitted feedback regarding the Chinese characters.
FB9639611
In my own code, I have used a similar scheme to yours, fuzzy querying Chinese Latin spelling results from CoreData data.
extension String{
func transformToLatin(hasBlank: Bool = false) -> String {
let stringRef = NSMutableString(string: self) as CFMutableString
CFStringTransform(stringRef,nil, kCFStringTransformToLatin, false)
CFStringTransform(stringRef, nil, kCFStringTransformStripCombiningMarks, false)
let pinyin = stringRef as String
return hasBlank ? pinyin : pinyin.replacingOccurrences(of: " ", with: "")
}
}
I will try again as you suggested.
.onRecevier(books.publisher){ Changs in
....
}