Кнопка панели инструментов появляется несколько разIOS

Программируем под IOS
Ответить
Гость
 Кнопка панели инструментов появляется несколько раз

Сообщение Гость »


I'm trying to implement a list of cards in a view that each has a textfield and values that changes based on the textfield input. I made a custom toolbar ontop of the numeric keyboard for the textfield. However, I had an issue with the toolbar button that is used to dismiss the keyboard once the user has entered the input.

Since I have a list of Card components in the parent view, the button "Done" would render the total Card components number of times in the toolbar. In the below example, the "Done" button is rendered three times, so is the back button for the parent view.

It seems to be a problem with navigation. Wrapping NavigationView around Card seems to resolve the issue, but then introduce a new issue of creating extra space between each Card component, which couldn't be eliminated with hiding the title, back button, or changing NavigationViewStyle.

How should I go about fixing this?


Изображение


parent view

struct DetailsView: View { @Environment(\.dismiss) var dismiss @EnvironmentObject var userService: UserService @EnvironmentObject var stockService: StockService @FocusState var focusedStock: Stock? @State var shares = [String: Double]() let stockListId: String var stockList: StockList{ userService.getStockList(byId: stockListId)! } var stocks: [Stock]{ stockService.stocks(withList: stockList) } @State var total: Double = .infinity var totalValue: Double{ var values: Double = 0 for stock in stocks{ values += stock.lastPrice * (shares[stock.id] ?? 0.0) } return values } var body: some View { NavContent(title: stockList.name){ ScrollView{ VStack{ RiskScoreView(stockList.riskScore) .padding(.bottom, -30) .padding(.top, 40) NavigationLink(destination: CompanySharesListView(stockListId: stockListId)){ HStack{ Text("Companies") .font(Font.custom("Open Sans", size: 20).weight(.bold)) .foregroundColor(.titleFont) Spacer() Image(systemName: "chevron.right") .resizable() .frame(width: 10, height: 18) .foregroundColor(.titleFont).padding(.trailing, 10) } } ForEach(stocks.indices, id:\.self){ index in if index < 3{ let stock = stocks[index] NavContent(title: ""){ Card(stock: stock, focusedStock: $focusedStock, total: $total, shares: $shares) } } } SmartNewsView(stockList: stockList).environmentObject(stockService) Spacer().frame(height: 80) }.padding(.horizontal, 20) } .onAppear{ shares = stockList.shares Task{ await stockService.fetchPrice(for: stockList) } total = totalValue }.onChange(of: shares){ _ in total = totalValue }.onDisappear{ Task{ stockList.shares = shares await userService.updateStocklist(with: stockList) } } } } } card view
import SwiftUI struct Card: View { @EnvironmentObject var stockService: StockService var stock: Stock var focusedStock: FocusState.Binding @Binding var total: Double @State var share: Double = 0 @Binding var shares: [String: Double] @State var stringInput: String = "" var value: Double{ stock.lastPrice*share } let formatter: NumberFormatter = { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 6 formatter.maximum = 9999999999 return formatter }() var body: some View { VStack (alignment: .leading, spacing: 4) { HStack(spacing: 10){ StockIcon(stock.id) Text(stock.id).font(.custom("OpenSans-SemiBold", size: 16)) Spacer() StockReturnArrow(stock: stock) }.padding(.bottom, 5) VStack(spacing: 10) { HStack { Text("Position Ratio").font(.custom("OpenSans-Regular", size: 12)) .foregroundColor(.gray) Spacer() Text("\(String(format:"%.3f%%", 100.0*value/total ))").font(.custom("OpenSans-Regular", size: 12)) } HStack { Text("Value").font(.custom("OpenSans-Regular", size: 12)) .foregroundColor(.gray) Spacer() Text("\(formatter.string(from: value as NSNumber)!) USD") .font(.custom("OpenSans-Regular", size: 12)) } HStack { Text("Shares").font(.custom("OpenSans-Regular", size: 12)) .foregroundColor(.gray) Spacer() } } Spacer().frame(height: 10) HStack(spacing: 5) { TextField("", value: $share, formatter: formatter) .font(Font.custom("Open Sans", size: 14)) .keyboardType(.decimalPad) .autocapitalization(.none) .focused(focusedStock, equals: stock) .toolbar { ToolbarItem(placement: .keyboard) { Button("Done") { focusedStock.wrappedValue = nil }.tint(.primaryGreen) } }.padding(.horizontal, 20) .background( RoundedRectangle(cornerRadius: 10) .stroke(.gray, lineWidth: 1) .frame(height: 44) .opacity(0.5) ) Spacer() HStack { Button(action: { if share >= 1 { share -= 1 } }) { Image(systemName: "minus") }.foregroundColor(.gray) Divider() .frame(height: 40) Button(action: { if share < 100000000 { share += 1 } }) { Image(systemName: "plus") }.foregroundColor(.gray) } .padding(.horizontal) .background( RoundedRectangle(cornerRadius: 10) .stroke(.gray, lineWidth: 1) .frame(height: 44) .opacity(0.5) ) } }//VStack .padding(.leading, 30) .padding(.trailing, 20) .padding(.vertical, 24) .background( RoundedRectangle(cornerRadius: 15) .overlay(RoundedRectangle(cornerRadius: 15).stroke( .lightGrey.opacity(0.05), lineWidth: 1 )) .foregroundColor(.white) .shadow(color: .lightGrey.opacity(0.15), radius: 10) ) .onChange(of: share){ newShare in shares[stock.id] = newShare let tmp = shares shares = tmp }.onAppear{ share = shares[stock.id] ?? 0 } } }

Источник: https://stackoverflow.com/questions/780 ... iple-times
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»