如何使用从第二个视图控制器传回的数据更新我的 UI?
How can I update my UI with data passed back from a second View Controller?
我正在开发一个小型股票应用程序,它根据用户select输入的价格显示股票。最初,当应用程序加载时,我会显示所有股票。但是,我实现了一个过滤器,当用户点击一个文本字段时,它会转到第二个视图控制器,并且用户必须 select 通过 select 一个单选按钮来选择他们想要的价格。我已经使用协议和委托成功地将用户输入传回并将其保存到 priceTarget 变量,但是,我不确定如何使用新价格更新 UI。我假设我必须重新加载我的 tableView 并使用更新后的价格再次获取数据。有人可以提供一些建议吗?
// pass user input back
@IBAction func priceBtnTap(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
switch sender.tag {
case 1:
delegate?.passPrice(price: oneDollarPriceLabel.text!)
case 2:
delegate?.passPrice(price: twoDollarPriceLabel.text!)
case 3:
delegate?.passPrice(price: threeDollarPriceLabel.text!)
case 4:
delegate?.passPrice(price: fourDollarPriceLabel.text!)
case 5:
delegate?.passPrice(price: fiveDollarPriceLabel.text!)
default:
print("Problem in priceBtnTap()")
}
func passPrice(price: String) {
priceTarget = price
print(priceTarget)
}
var priceTarget = "10"
//MARK: - Fetch stockDta
func fetchData() {
guard let urlString = URL(string: "https://financialmodelingprep.com/api/v3/stock-screener?sector=technology&priceLowerThan=\(priceTarget)&exchange=NYSE,NASDAQ,AMEX&limit=100&apikey=\(Api.key)") else {
fatalError("Wrong endpoint")
}
let dataTask = session.dataTask(with: urlString) { [self] (data, _, error) in
if error != nil {
print("opps, we have a problem")
return
}
if let payload = data {
guard let stockInfo = try? JSONDecoder().decode([StockData].self, from: payload) else {
print("issue decoding data")
return
}
self.stockArray.append(contentsOf: stockInfo)
//MARK: - iterate over the stock data and save all the stock symbols in a new array
for stockSymbol in stockInfo {
self.stockSymbolArray.append(stockSymbol.symbol!)
}
//MARK: - Call the fetchStockChangeData() and pass the stockSymbolArray as a paramater of the function
fetchStockChangeData(stock: stockSymbolArray)
}
DispatchQueue.main.async {
self.tabelview.reloadData()
}
}
dataTask.resume()
}
你的思路是正确的。当用户点击按钮并且委托调用 passPrice(price:)
时,只需在该任务结束时调用 fetchData()
。
请记住,点击按钮时 table 视图在屏幕上显示的单元格专门呈现 stockArray
中的内容。因此,修改 stockArray
时要小心,因为如果新数据获取导致不同大小的数组,或者在用户主动滚动浏览 table 视图时解析结果相对耗时,它可能会产生不需要的副作用,例如奇怪地渲染单元格,甚至会导致应用程序崩溃的致命越界错误。因此,我建议在您填充结果的数据 return 中创建一个本地数组(闭包范围的本地数组),然后在重新加载 table 之前将结果交给 stockArray
查看:
if let payload = data {
var tempArray = [StockData]() // instantiate local/temp array
// modify temp array safely without fear of side effects
}
DispatchQueue.main.async {
self.stockArray = tempArray // hand off to data source right before reloading
self.tabelview.reloadData()
}
我正在开发一个小型股票应用程序,它根据用户select输入的价格显示股票。最初,当应用程序加载时,我会显示所有股票。但是,我实现了一个过滤器,当用户点击一个文本字段时,它会转到第二个视图控制器,并且用户必须 select 通过 select 一个单选按钮来选择他们想要的价格。我已经使用协议和委托成功地将用户输入传回并将其保存到 priceTarget 变量,但是,我不确定如何使用新价格更新 UI。我假设我必须重新加载我的 tableView 并使用更新后的价格再次获取数据。有人可以提供一些建议吗?
// pass user input back
@IBAction func priceBtnTap(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
switch sender.tag {
case 1:
delegate?.passPrice(price: oneDollarPriceLabel.text!)
case 2:
delegate?.passPrice(price: twoDollarPriceLabel.text!)
case 3:
delegate?.passPrice(price: threeDollarPriceLabel.text!)
case 4:
delegate?.passPrice(price: fourDollarPriceLabel.text!)
case 5:
delegate?.passPrice(price: fiveDollarPriceLabel.text!)
default:
print("Problem in priceBtnTap()")
}
func passPrice(price: String) {
priceTarget = price
print(priceTarget)
}
var priceTarget = "10"
//MARK: - Fetch stockDta
func fetchData() {
guard let urlString = URL(string: "https://financialmodelingprep.com/api/v3/stock-screener?sector=technology&priceLowerThan=\(priceTarget)&exchange=NYSE,NASDAQ,AMEX&limit=100&apikey=\(Api.key)") else {
fatalError("Wrong endpoint")
}
let dataTask = session.dataTask(with: urlString) { [self] (data, _, error) in
if error != nil {
print("opps, we have a problem")
return
}
if let payload = data {
guard let stockInfo = try? JSONDecoder().decode([StockData].self, from: payload) else {
print("issue decoding data")
return
}
self.stockArray.append(contentsOf: stockInfo)
//MARK: - iterate over the stock data and save all the stock symbols in a new array
for stockSymbol in stockInfo {
self.stockSymbolArray.append(stockSymbol.symbol!)
}
//MARK: - Call the fetchStockChangeData() and pass the stockSymbolArray as a paramater of the function
fetchStockChangeData(stock: stockSymbolArray)
}
DispatchQueue.main.async {
self.tabelview.reloadData()
}
}
dataTask.resume()
}
你的思路是正确的。当用户点击按钮并且委托调用 passPrice(price:)
时,只需在该任务结束时调用 fetchData()
。
请记住,点击按钮时 table 视图在屏幕上显示的单元格专门呈现 stockArray
中的内容。因此,修改 stockArray
时要小心,因为如果新数据获取导致不同大小的数组,或者在用户主动滚动浏览 table 视图时解析结果相对耗时,它可能会产生不需要的副作用,例如奇怪地渲染单元格,甚至会导致应用程序崩溃的致命越界错误。因此,我建议在您填充结果的数据 return 中创建一个本地数组(闭包范围的本地数组),然后在重新加载 table 之前将结果交给 stockArray
查看:
if let payload = data {
var tempArray = [StockData]() // instantiate local/temp array
// modify temp array safely without fear of side effects
}
DispatchQueue.main.async {
self.stockArray = tempArray // hand off to data source right before reloading
self.tabelview.reloadData()
}