here is minimal reproducible example:
import SwiftUI
struct ContentView: View {
@State var options = ["1","2","3","4"]
@State var option = "1"
var body: some View {
ForEach(options, id: \.self) { item in
Button(item, action: {
self.option = item
})
}
ChildView(model: .init(option: option))
}
}
class ChildViewModel: ObservableObject {
@Published var option: String
init(option: String) {
self.option = option
}
}
struct ChildView: View {
@ObservedObject var model: ChildViewModel
var body: some View {
Text(model.option)
Button("Tab", action: {
print("Option: \(model.option)")
})
.keyboardShortcut("f")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Here is steps to reproduce:
click "2" item
click "Tab" Button, which will prints "Option: 2"
press Cmd+F, which will prints "Option: 1"
step(3) is unexpected behavior, since it has to print "Option: 2"
If you change Button("Tab") into Button("Tab (model.option)"), step 3 will produce proper result of printing "Option: 2"
So i assume this is issue of keyboardShortcut not properly referencing "latest" action - unless "label" of button changes, keyboardShortcut does not use latest "action" that is given.
but as you can see from example, clicking button will result calling latest action
Post
Replies
Boosts
Views
Activity
here is a minimal reproducible example, on macOS
struct ContextMenuTest1: View {
@State var visible: Bool = true
var body: some View {
Button(action: { self.visible.toggle() }, label: { Text("ContextMenuTest2 Toggle") })
if self.visible {
ChildView()
}
}
struct ChildView: View {
class Model: ObservableObject {
init() {
print("Model Created")
}
deinit {
print("This will never be called")
}
func someAction() {
}
}
var body: some View {
Text("Text That has Context Menu")
.contextMenu {
ContextMenu()
}
}
struct ContextMenu: View {
@StateObject var model: Model = .init()
var body: some View {
Button(action: {
self.model.someAction()
}, label: {
Text("Context Menu Button 1")
})
}
}
}
}
step to reproduce :
right click on Text("Text That has Context Menu") to open contextMenu()
turn off the contextMenu
click "ContextMenuTest2 Toggle"
This should have destroyed both ChildView and ChildView.ContextMenu, thus should have deallocated ChildView.Model
but ChildView.Model.deinit never be called.
I understand .contextMenu() document show examples of putting Button directly, but it doesn't mention or block attempts of putting custom view directly like this - in which case, Button.action closure it permanent memory leaked. unless you kill the application
hope that clairify the bug, thanks!