单击表格行时,SecondViewController 上显示的信息错误
Posted
技术标签:
【中文标题】单击表格行时,SecondViewController 上显示的信息错误【英文标题】:Wrong information displayed on SecondViewController when table row clicked 【发布时间】:2017-06-27 11:15:39 【问题描述】:我第一次尝试构建一个分组而不是简单的 tableView,但在点击单元格时显示的信息不正确。
首先,我创建了一个数组,该数组用于为我的组指定标题。接下来我有一个数组,其中包含另外 4 个数组,每个数组包含 8 个对象,而最后一个只有 1 个对象,这 4 个数组是我的组部分。
当应用程序运行时,组表会完全按照它应该显示的方式显示,但是当您单击特定行时,它可能会显示应该用于不同行的信息。我从数组中删除一些对象只是为了使代码更短,以便您在此处查看。
符文:
import UIKit
struct Rune
var runeName: String
var runeImage: UIImage
var runeDescription: String
视图控制器:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
@IBOutlet weak var tableView: UITableView!
var runeTitle = [["Freyr/Freya's Aett"], ["Heimdall's Aett"], ["Tyr's Aett"], ["Additional Runes"]]
let runes = [[Rune(runeName: "Fehu", runeImage: UIImage(named: ("Fehu.png"))!, runeDescription: "(F: Domestic cattle, wealth.) Possessions won or earned, earned income, luck. Abundance, financial strength in the present or near future. Sign of hope and plenty, success and happiness. Social success. Energy, foresight, fertility, creation/destruction (becoming).\n\n Fehu Reversed or Merkstave: Loss of personal property, esteem, or something that you put in effort to keep. It indicates some sort of failure. Greed, burnout, atrophy, discord. Cowardice, stupidity, dullness, poverty, slavery, bondage."),
Rune(runeName: "Wunjo", runeImage: UIImage(named: ("Wunjo.png"))!, runeDescription: "(W or V: Joy.) Joy, comfort, pleasure. Fellowship, harmony, prosperity. Ecstasy, glory, spiritual reward, but also the possibility of going \"over the top\". If restrained, the meaning is general success and recognition of worth.\n\n Wunjo Reversed or Merkstave: Stultification, sorrow, strife, alienation. Delirium, intoxication, possession by higher forces, impractical enthusiasm. Raging frenzy, berzerker.")],
[Rune(runeName: "Hagalaz", runeImage: UIImage(named: ("Hagalaz.png"))!, runeDescription: "(H: Hail.) Wrath of nature, destructive, uncontrolled forces, especially the weather, or within the unconscious. Tempering, testing, trial. Controlled crisis, leading to completion, inner harmony. Hagalaz Merkstave (Hagalaz cannot be reversed, but may lie in opposition): Natural disaster, catastrophe. Stagnation, loss of power. Pain, loss, suffering, hardship, sickness, crisis."),
Rune(runeName: "Sowilo", runeImage: UIImage(named: ("Sowilo.png"))!, runeDescription: "(S: The sun.) Success, goals achieved, honor. The life-force, health. A time when power will be available to you for positive changes in your life, victory, health, and success. Contact between the higher self and the unconscious. Wholeness, power, elemental force, sword of flame, cleansing fire. Sowilo Merkstave (Sowilo cannot be reversed, but may lie in opposition): False goals, bad counsel, false success, gullibility, loss of goals. Destruction, retribution, justice, casting down of vanity. Wrath of god.")],
[Rune(runeName: "Tiwaz", runeImage: UIImage(named: ("Tiwaz.png"))!, runeDescription: "(T: Tyr, the sky god.) Honor, justice, leadership and authority. Analysis, rationality. Knowing where one's true strengths lie. Willingness to self-sacrifice. Victory and success in any competition or in legal matters.\n\n Tiwaz Reversed or Merkstave: One's energy and creative flow are blocked. Mental paralysis, over-analysis, over-sacrifice, injustice, imbalance. Strife, war, conflict, failure in competition. Dwindling passion, difficulties in communication, and possibly separation."),
Rune(runeName: "Othala", runeImage: UIImage(named: ("Othala.png"))!, runeDescription: "(O: Ancestral property.) Inherited property or possessions, a house, a home. What is truly important to one. Group order, group prosperity. Land of birth, spiritual heritage, experience and fundamental values. Aid in spiritual and physical journeys. Source of safety, increase and abundance.\n\n Othala Reversed or Merkstave: Lack of customary order, totalitarianism, slavery, poverty, homelessness. Bad karma, prejudice, clannishness, provincialism. What a man is bound to.")],
[Rune(runeName: "Blank Rune", runeImage: UIImage(named: ("Blank.png"))!, runeDescription: "There is no historical support for a \"Blank Rune\" in runic divination. It was invented in the 1980's. It should not be used in a rune casting. If you bought a rune set with a blank piece, save it in case you lose another rune piece, but don't use it in rune casting.")]]
func numberOfSections(in tableView: UITableView) -> Int
// #warning Incomplete implementation, return the number of sections
return runes.count
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// #warning Incomplete implementation, return the number of rows
return runes[section].count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
// Configure the cell...
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as UITableViewCell;
let item = runes[indexPath.section][indexPath.row]
cell.imageView?.image = item.runeImage
cell.textLabel?.text = item.runeName
cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
return cell
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
return String(describing: runeTitle[section][0])
var clickedIndex = 0
var section = 0
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
self.clickedIndex = indexPath.row
self.section = indexPath.section
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "segue"
let runeArray = runes[section][clickedIndex]
let destinationVC = segue.destination as! SecondViewController
destinationVC.selectedRune = runeArray
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
SecondViewController:
import UIKit
class SecondViewController: UIViewController
var selectedRune: Rune!
@IBOutlet weak var runeNameLabel: UILabel!
@IBOutlet weak var runeImage: UIImageView!
@IBOutlet weak var runeDescriptionLabel: UILabel!
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
runeNameLabel.text = selectedRune.runeName
runeImage.image = selectedRune.runeImage
runeDescriptionLabel.text = selectedRune.runeDescription
【问题讨论】:
相关:Xcode: Passing Information from UITableViewController to UIViewController 嗨@NiravD 我曾尝试过与此代码类似的东西,结果与我现在的结果完全相同,但我不确定为什么会这样,我使用了这两行: tableView.indexPathForSelectedRow destinationVC.selectedRune = runeArray[(indexPath?.row)!] 但结果仍然相同。有什么想法吗? 用您正在尝试的代码编辑您的问题以及您如何创建 segue,是来自UITableViewCell
还是来自ViewController
?
在我的问题中更新了代码,我从单元格中拖出了 ctrl
你有二维数组所以它应该像if let indexPath = self.tableView.indexPathForSelectedRow destinationVC.selectedRune = runes[indexPath.section][indexPath.row]
【参考方案1】:
你有这个
func numberOfSections(in tableView: UITableView) -> Int
// #warning Incomplete implementation, return the number of sections
return runes.count
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// #warning Incomplete implementation, return the number of rows
return runes[section].count
因此,除了获取 indexPath.row 之外,您还需要获取当前选定的部分。例如,
self.clickedIndex = indexPath.row
self.section = indexPath.section
然后您选择的 runArray 将是
let runeArray = runes[section][clickedIndex]
更新
您的问题是 prepare:forSegue
在调用 tableview:didSelectRowAt
之前被调用。您应该使用它们中的任何一个而不是两者。下面的 sn-p 展示了如何使用 navigationtroller.pushViewController
导航到另一个视图控制器。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
section = indexPath.section
clickedIndex = indexPath.row
let runeArray = runes[section][clickedIndex]
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let destinationVC = storyboard.instantiateViewController(withIdentifier: "SecondVC") as? SecondViewController else return
destinationVC.selectedRune = runeArray
navigationController?.pushViewController(destinationVC, animated: true)
记得将 Storyboard ID
设置为 SecondVC 或任何你想要的。
【讨论】:
使用您的更改几乎可以正常工作,只需解决一个小错误。当我第一次点击新部分中的一行时,我得到了错误的数据,但之后我点击的每一行都是完美的,它总是相同的错误数据,例如我点击第二部分中的一行它会给我第一节的第一个条目,如果我单击第三节中的一行,它将给我第二节的第一个条目。除此之外,它完美无缺。如果这可以解决,那是谢天谢地解决的全部问题 所以你的runArray
实际上不是一个数组,而是一个实例。请检查我编辑的答案。
每次我使用新的更新代码启动应用程序(参见上面的编辑),无论我点击哪一行,我都会得到 section[0] clickedIndex[0],然后当我点击返回并点击另一个row 它将显示先前单击的行的数据,看起来这样做是因为我的 section 和 clickedIndex 变量最初设置为 0 我尝试将其更改为 var section: Int!和 var clickedIndex: Int!但这会使我的应用程序崩溃。我很困惑这里出了什么问题
这是因为您的 segue
函数在 didSelectRowAt
之前被调用。检查我更新的答案。【参考方案2】:
最好的方法是: 1. 在表格视图单元格中创建一个项目对象(在 YourtableViewCell.h 和 YourtableViewCell.m 中)。 2.然后在单元格中分配该项目(在 cellForRowAtIndex 方法中) 3.然后在
didSelectRowAt
-
现在您可以通过该选定单元格获取该项目。
【讨论】:
【参考方案3】:为 indexpath.section 创建一个变量 在 didSelectRow 中初始化它
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "segue"
let runeArray = runes[
let item = runes[indexPath.section][indexPath.row] ]// variable runeArray is the child array from runes
let destinationVC = segue.destination as! SecondViewController
destinationVC.selectedRune = runeArray[indexpath.section ]// Now choose an actual Rune object from the array by index.
【讨论】:
以上是关于单击表格行时,SecondViewController 上显示的信息错误的主要内容,如果未能解决你的问题,请参考以下文章