我的UIKit应用程序中显示了基于数据的SwiftUI视图。我想做的是基于UIKit中的按钮点击更改SwiftUI视图,只是为了测试。我还不太擅长绑定。现在在我的按钮代码中,我不确定如何影响更改(即突出显示第二项)。
以下是我当前的设置:
struct PresetBank: Identifiable
{
var id: UUID
let index: Int
var title: String
var iconString: String
var presetsCount: Int
var isSelected: Bool = false
}
class PresetStore: ObservableObject
{
@Published var arrayOfPresets: [PresetBank]
init(arrayOfPresets: [PresetBank]) {
self.arrayOfPresets = arrayOfPresets
}
public func selectBank(index: Int) {
print(index)
// How can I change the PresetBank items isSelected
// in order to update their UI? I can loop through
// and change the prop, but it does nothing.
for i in 0..<arrayOfPresets.count - 1 {
arrayOfPresets[i].isSelected = false
}
arrayOfPresets[index].isSelected = true
// The properties change, but the UI does not update.
// I am missing something here.
}
}
struct PresetBankView: View
{
var bank: PresetBank
@State var isSelected: Bool
var body: some View
{
ZStack
{
VStack {
Text(bank.title)
.multilineTextAlignment(.center)
.fontWeight(.medium)
.foregroundColor(bank.isSelected == true ? .white : .black)
.font(.system(size: 12))
.minimumScaleFactor(0.5)
.lineLimit(2)
.padding(.top, 10)
.padding(.leading, 5)
.padding(.trailing, 5)
Spacer()
Text("\(bank.presetsCount)")
.multilineTextAlignment(.center)
.font(.system(size: 10))
.foregroundColor(bank.isSelected == true ? .white : .black)
.padding(.bottom, 10)
}
ZStack {
Image(systemName: bank.iconString)
.font(.system(size: 26))
.foregroundColor(bank.isSelected == true ? .white : .black)
}.padding(.top, 10)
}
.frame(width: 100, height: 100)
.background {
RoundedRectangle(cornerRadius: 8)
.aspectRatio(contentMode: .fill)
.foregroundColor(bank.isSelected == true ? .black : .white)
.shadow(color: .black.opacity(0.3), radius: 5, x: 0, y: 0)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(.gray, lineWidth: 2)
)
}
Spacer()
.frame(width: 15)
}
}
struct ContentView: View
{
@State var store: PresetStore
var body: some View
{
ScrollView(.horizontal)
{
HStack {
// Pull in and use the data passed in from UIKit.
ForEach(store.arrayOfPresets) { bank in
PresetBankView(bank: bank, isSelected: bank.isSelected)
}
}
.padding()
}
}
}
...
class ViewController: UIViewController
{
var thisStore: PresetStore!
override func viewDidLoad()
{
super.viewDidLoad()
let arrayOfPresets:[PresetBank] = []
thisStore = PresetStore(arrayOfPresets: arrayOfPresets)
let p1: PresetBank = PresetBank(id: UUID(), index: 0, title: "Default", iconString: "music.note.house", presetsCount: 5, isSelected: true)
let p2: PresetBank = PresetBank(id: UUID(), index: 1, title: "Relaxation", iconString: "figure.mind.and.body", presetsCount: 2)
let p3: PresetBank = PresetBank(id: UUID(), index: 2, title: "Dinner Party on Sunday Afternoon", iconString: "wineglass.fill", presetsCount: 3)
let p4: PresetBank = PresetBank(id: UUID(), index: 3, title: "Workout", iconString: "figure.run", presetsCount: 5)
let p5: PresetBank = PresetBank(id: UUID(), index: 4, title: "Sleepy Time", iconString: "powersleep", presetsCount: 2)
thisStore.arrayOfPresets.append(p1)
thisStore.arrayOfPresets.append(p2)
thisStore.arrayOfPresets.append(p3)
thisStore.arrayOfPresets.append(p4)
thisStore.arrayOfPresets.append(p5)
let contentView = UIHostingController(rootView: ContentView(store: thisStore))
addChild(contentView)
view.addSubview(contentView.view)
contentView.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 200)
}
@IBAction func testSelect(_ sender: UIButton) {
thisStore.selectBank(index: 1)
}
}
所以你可以在selectBank
方法中看到我想要遍历所有的PresetBank
并将它们的isSelected
更改为false
,然后通过索引将一个设置为true
-并更新视图,目前我还不清楚如何实现这一点。
2条答案
按热度按时间tjvv9vkg1#
我认为这解决了问题。下面是我更新的代码:
现在从UIKit更新很好。我有3个测试按钮,并循环通过SwiftUI视图
isSelected
属性。接下来让SwiftUI更新自己和UIKit。qqrboqgw2#
您可以像这样替换宿主控制器上的数据结构: