私は、異なる銀行の2つのリストが通貨レートを示すプロジェクトを持っています。そして、最初のリストで通貨を選択すると、2番目のリストが同じ通貨に自動スクロールされます。ボタン付きのチュートリアルを見ましたが、必要なものではありません。onTapGesture を使用することを考えましたが、正しい方法で使用する方法がわかりません。ExchangeRatesPB(ccy) と ExchangeRatesNBU(cc) には、「USD」、「EUR」、「RUR」などの一部の通貨の同じ短い名前があります。とにかく助けてくれてありがとう。
struct ContentView: View {
@State private var date = Date()
@State var currenciesPB: [ExchangeRatesPB] = []
@State var currenciesNBU: [ExchangeRatesNBU] = []
@State var scrollToCurrency: String = ""
var body: some View {
ZStack {
Color(.systemGray6)
.edgesIgnoringSafeArea(.all)
VStack {
HStack {
Spacer(minLength: 110)
Text("Exchange rates")
.font(.title2)
.padding()
Spacer()
Image(systemName: "chart.bar.xaxis")
.font(.title)
.padding()
}
.foregroundColor(.white)
.padding(.top)
.background(Color.init(#colorLiteral(red: 0.4558259845, green: 0.5886077285, blue: 0.5515387654, alpha: 1)))
.edgesIgnoringSafeArea(.top)
//PB
VStack {
HStack {
Text("PrivatBank")
.foregroundColor(Color.init(#colorLiteral(red: 0.3549223542, green: 0.3776315749, blue: 0.4196012616, alpha: 1)))
Spacer(minLength: 100)
Image(systemName: "calendar")
.foregroundColor(.gray)
DatePicker("", selection: $date, displayedComponents: .date)
}
.font(.title2)
.padding(10)
HStack(spacing: 60) {
Text("Currency")
Text("Purchase")
Text("Sale")
} .foregroundColor(.gray)
VStack {
// ScrollView {
List(currenciesPB, id: \.self) { currencyPB in
VStack {
HStack(spacing: 60) {
Text(currencyPB.ccy)
.id(currencyPB.ccy)
Text(currencyPB.sale)
Text(currencyPB.buy)
}
// .onTapGesture {
//scrollToCurrency = currencyPB.ccy
//print(scrollToCurrency)
// }
.foregroundColor(Color.init(#colorLiteral(red: 0.3549223542, green: 0.3776315749, blue: 0.4196012616, alpha: 1)))
}
}
// }
.padding(.top)
.onAppear() {
ApiPB().getCurrency { (currenciesPB) in
self.currenciesPB = currenciesPB
}
}
}
}
//NBU
VStack {
HStack {
Text("NBU")
.foregroundColor(Color.init(#colorLiteral(red: 0.3549223542, green: 0.3776315749, blue: 0.4196012616, alpha: 1)))
Spacer(minLength: 150)
Image(systemName: "calendar")
.foregroundColor(.gray)
DatePicker("", selection: $date, displayedComponents: .date)
}
.font(.title2)
.padding(10)
// ScrollView {
ScrollViewReader { value in
VStack {
List(currenciesNBU, id: \.self) { currencyNBU in
VStack {
HStack(spacing: 50) {
Text(currencyNBU.txt)
Spacer()
VStack {
HStack {
Text(String(currencyNBU.rate))
Text("UAH")
}
}
}
.listRowBackground(Color(.systemGray6))
.foregroundColor(Color.init(#colorLiteral(red: 0.3549223542, green: 0.3776315749, blue: 0.4196012616, alpha: 1)))
}
}
.onChange(of: scrollToCurrency) { _ in
value.scrollTo(scrollToCurrency, anchor: .top)
}
.padding(.top)
.onAppear() {
ApiNBU().getCurrency { (currenciesNBU) in
self.currenciesNBU = currenciesNBU
}
}
}
}
// }
}
}
}
}
}
struct ExchangeRatesPB: Codable, Hashable {
let ccy: String
let base_ccy: String
var buy: String
var sale: String
}
class ApiPB {
func getCurrency(completion: @escaping ([ExchangeRatesPB]) -> ()) {
guard let url = URL(string: "https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
let currenciesPB = try! JSONDecoder().decode([ExchangeRatesPB].self, from: data!)
DispatchQueue.main.sync {
completion(currenciesPB)
}
}
.resume()
}
}
struct ExchangeRatesNBU: Codable, Hashable {
let r030: Int
let txt: String
var rate: Double
var cc: String
}
class ApiNBU {
func getCurrency(completion: @escaping ([ExchangeRatesNBU]) -> ()) {
guard let url = URL(string: "https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?date=20200302&json") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
let currenciesNBU = try! JSONDecoder().decode([ExchangeRatesNBU].self, from: data!)
DispatchQueue.main.sync {
completion(currenciesNBU)
}
}
.resume()
}
}