UITableViewCellsで問題が発生しています。 UITableViewをAPIに接続して、セルにデータを入力しました。
次に、_indexPath.row
_を取得して、RestaurantViewController
に送信する必要がある配列内のJSONオブジェクトを識別する関数を作成しました。
これが、小さなスニペットが「行クリック」をグローバル変数に設定する方法です。
_func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
i = indexPath.row
}
_
そして、ここに私のprepareForSegue()
関数があります。これは私のプッシュセグエをRestaurantViewController
に接続する必要があります。
_override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toRestaurant"{
let navigationController = segue.destinationViewController as UINavigationController
let vc = navigationController.topViewController as RestaurantViewController
vc.data = currentResponse[i] as NSArray
}
}
_
そして、これがUITableViewCell
からセグエを設定する方法です
これが私の結果です。これらのセルを1つずつクリックしようとしましたが、別のviewControllerにプッシュされません...エラーも発生しません。ここで何が問題になっていますか?
機能しないソリューションを試しました
_override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toRestaurant"{
let vc = segue.destinationViewController as RestaurantViewController
//let vc = navigationController.topViewController as RestaurantViewController
vc.data = currentResponse[i] as NSArray
}
}
_
問題は、データを正しく処理していないことです。 currentResponse
配列を調べると、NSDictionariesが保持されていることがわかりますが、prepareForSegue
でNSDictionaryをNSArrayにキャストしようとすると、アプリがクラッシュします。
data
のRestaurantViewController
変数をNSDictionaryに変更し、prepareForSegue
を変更してNSDictionaryを渡す
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if let cell = sender as? UITableViewCell {
let i = redditListTableView.indexPathForCell(cell)!.row
if segue.identifier == "toRestaurant" {
let vc = segue.destinationViewController as RestaurantViewController
vc.data = currentResponse[i] as NSDictionary
}
}
}
次の手順で問題を解決できます。そうでない場合は、お知らせください。
tableView(tableView, didSelectRowAtIndexPath:)
実装を削除します。
data
のRestaurantViewController
の型をNSDictionary!
にします
prepareForSegue
で選択されている行を特定します。
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if let cell = sender as? UITableViewCell {
let i = tableView.indexPathForCell(cell)!.row
if segue.identifier == "toRestaurant" {
let vc = segue.destinationViewController as RestaurantViewController
vc.data = currentResponse[i] as NSDictionary
}
}
}
ソフトウェアが標準の2レベルのテーブルビュー構造と大きく異なる理由を理解できません。そこで、このリンクからアクセスできる短い例をコーディングしました。以下のソースコードも含めました。
プログラムはあなたが持っているものを模倣しています(私が理解している限り)。テーブルコントローラー1は、テーブルビューセルからテーブルコントローラー2にセグエします。セグエイングに問題はありませんでした。セグエを開始するためにストーリーブックを拡張する必要がないことを確認してください。
両方のコントローラーをナビゲーションコントローラーに埋め込みました。私の経験では、ナビゲーションを設定するための多くの労力が節約されます。
または、画面上部の最初のTableViewControllerシンボルから2番目のコントローラーまでコントロールをドラッグして、セグエを設定することもできます。
推奨される方法ではありませんが、グローバル変数(selectedRow)を使用しました。しかし、prepareForSegueを使用してRestaurantTableViewControllerに変数を設定するのと同じくらい簡単です(例を示します)。
残念ながら、コードを適切にフォーマッターで取得できません
import UIKit
var selectedRow = -1
class TableViewController: UITableViewController {
var firstArray = ["Item1","Item2","Item3","Item4"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return firstArray.count
}
let nameOfCell = "RestaurantCell"
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell
cell.textLabel!.text = firstArray[indexPath.row]
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row
}
// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let vc = segue.destinationViewController as RestaurantTableViewController
// can write to variables in RestaurantTableViewController if required
vc.someVariable = selectedRow
}
}
import UIKit
class RestaurantTableViewController: UITableViewController {
var secondArray = ["Item 2.1", "Item 2.2", "Item 2.3", "Item 2.4"]
var someVariable = -1
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return secondArray.count
}
let nameOfCell = "RestaurantCell"
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell
cell.textLabel!.text = secondArray[indexPath.row]
if indexPath.row == selectedRow {
cell.textLabel!.text = cell.textLabel!.text! + " SELECTED"
}
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row
}
}
ストーリーボードのスクリーンショットで、セグエが最初のプロトタイプセルをRestaurantViewController
に接続していることに気付きました。このプロトタイプセルは、右側に開示インジケータアクセサリが付いた「基本」スタイルのセルのように見えます。ただし、実行中のアプリのスクリーンショットを見てください。テーブルには、右側に開示インジケータアクセサリがないセルの「サブタイトル」スタイルのように見えるセルが入力されています。
セグエが特定のプロトタイプセルに対してのみ機能するように構成されているにもかかわらず、セグエが実行されない理由は、テーブルにデータを入力するときにそのプロトタイプセルが使用されないためです。 _tableView:cellForRowAtIndexPath:
_で何をしている場合でも、必要なプロトタイプセルを使用していません。
@Starscreamは、適切なセルを適切な識別子でデキューし、それをInterface Builderのプロトタイプセルの識別子と照合する適切なアイデアを持っています。それを行った後でも発生するクラッシュは、上記のコメントで述べた以前の問題が原因である可能性があります。ストーリーボードのセグエは明らかにUITableViewController
を指しています。 RestaurantViewController
がUITableViewController
のサブクラスである限り、_prepareForSegue:sender:
_のコードは_let vc = segue.destinationViewController as RestaurantViewController
_である必要があります。 UINavigationController
としてキャストしようとするとクラッシュします。また、ストーリーボードの宛先UITableViewController
のクラスが、[Identity Inspector]ペインでRestaurantController
としてリストされていることを確認してください。ストーリーボードにジェネリックUITableViewController
が含まれているだけでプログラムがコンパイルされるとクラッシュします。
元の問題にさらに戻ると、_tableView:cellForRowAtIndexPath:
_をどのように実装したかわかりません。これは重要かもしれません。多分それはそれほど単純ではありません。おそらく、多くのプロトタイプセルを処理するか、実行時にカスタムセルを生成することを計画しています。この場合、これを簡単にする1つの方法は、ユーザーがセルをタップしたときにプログラムでセグエを実行することです。特定のプロトタイプセルを使用する代わりに、セグエを "Restaurangernäramig" UITableViewController
からRestaurantViewController
に向かう接続にしてください。 (Interface Builderで接続するには、最初のアイコンの上部にあるTable View Controllerアイコンから2番目の本体にドラッグしてControlキーを押しながらクリックします)。これを有効にするには、属性インスペクタペインでこのセグエに識別子を与える必要があります。 _"toRestaurant"
_だとしましょう。次に、_tableView:didSelectRowAtIndexPath:
_メソッドの最後に、次のコード行を挿入します:self.performSegueWithIdentifier("toRestaurant", sender: self)
。テーブルで選択されているセルに関係なく、このセグエは常に起動します。
私は今Swiftに入っているのでここで気まぐれに出かけますが、prepareForSegue()
でそれを行う方法は次のようなものです:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toRestaurant"{
let navigationController = segue.destinationViewController as UINavigationController
let vc = navigationController.topViewController as RestaurantViewController
//notice I changed [i] to [index!.row]
vc.data = currentResponse[index!.row] as NSArray
}
}
私には、クラスのメソッド内のプライベート変数のようなi変数を呼び出しているように見えます。 @Syed TariqがselectRow
変数を使用して行ったようなことを実行し、class SomeController: UIViewController /*, maybe some more here? */ {
の上に設定して、変数を内部で署名できます。
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row
}
上記のような方法ですが、どちらの方法もかなりうまくいくはずです。
cellForRow
メソッドで次のようなセルを作成してみてください:
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MyTestCell", forIndexPath: indexPath)
私は同じ問題を抱えていましたが、解決策は次のとおりです:
performSegueWithIdentifier( "toViewDetails"、sender:self)
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var cellnumber = procMgr.processos[indexPath.row].numero
println("You selected cell #\(indexPath.row)")
println(cellnumber)
performSegueWithIdentifier("toViewDetails", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "toViewDetails" {
let DestViewController : ViewDetails = segue.destinationViewController as! ViewDetails
}
}
UItableviewの選択されたセルインデックスを取得する必要がある場合があります。以下のコードは、選択されたセルインデックス(UItableview.indexPathForSelectedRow)を使用して、配列の正しい要素を取得しました。
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "seguaVisitCardDetial" {
let viewController = segue.destinationViewController as! VCVisitCardDetial
viewController.dataThisCard = self.listOfVisitCards[(tblCardList.indexPathForSelectedRow?.row)!]
}
}