私は現在、UISwitchを含むカスタマイズされたUITableViewCell(XCodeで設計)を備えたUITableViewを備えたMonotouchフレームワークを使用してIOS用のアプリケーションを作成しています。
UITableViewSourceを介してセルを管理していますが、セルのスイッチのイベントUISwitch.ValueChangedに割り当てられたデリゲートメソッドへのコールバックを管理しているときに明らかに問題があります。
これが私が取り組んでいるUITableViewSourceコードです、それはもっと明確かもしれません:
// This class manages the TableView content and its rows
class MyTableViewDelegate : UITableViewSource
{
SatellitesViewController satController;
List<long> allocatedCells;
public MyTableViewDelegate (SatellitesViewController controller)
{
satController = controller;
allocatedCells = new List<long>();
}
public override int RowsInSection (UITableView tableview, int section)
{
return satController.sats.Count;
}
// Called when the switch to show the satellite's display state is touched
public void showButtonHandler(object sender, EventArgs e)
{
System.Console.WriteLine("SHOW BUTTONHANDLER");
if (sender != null)
{
CustomSwitch switchButton = (CustomSwitch) sender;
TLEForRedis satToShow = this.satController.getSatTLEs(switchButton.idSat, false);
if (satToShow != null)
{
if (switchButton.On == true)
this.satController.glView.showSatellite(satToShow);
else
this.satController.glView.hideSatellite(satToShow.Id);
}
}
}
// Called when the switch to show the satellite's display state is touched
public void orbitButtonHandler(object sender, EventArgs e)
{
System.Console.WriteLine("ORBIT BUTTONHANDLER");
if (sender != null)
{
CustomSwitch orbitButton = (CustomSwitch) sender;
TLEForRedis satToShow = this.satController.getSatTLEs(orbitButton.idSat, false);
if (satToShow != null)
this.satController.glView.setSatelliteOrbitDisplayState(satToShow.Id, orbitButton.On);
}
}
// Create the cell at indexPath
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
string cellName;
string nibName;
cellName = "PROTO_CELL";
nibName = "CellView";
// Get the table cell which is described in the CellView.xib interface
var cell = tableView.DequeueReusableCell(cellName) as CellView;
if (cell == null)
{
cell = new CellView();
var views = NSBundle.MainBundle.LoadNib(nibName, cell, null);
cell = Runtime.GetNSObject( views.ValueAt(0) ) as CellView;
}
// Modify the cell with its own data
SatsList sat = (SatsList) satController.sats [indexPath.Row];
CustomSwitch showButton = (CustomSwitch)cell.ViewWithTag(1);
UILabel satName = (UILabel)cell.ViewWithTag(2);
UILabel catalogNumber = (UILabel)cell.ViewWithTag(3);
CustomSwitch favoriteButton = (CustomSwitch)cell.ViewWithTag(4);
CustomSwitch orbitButton = (CustomSwitch)cell.ViewWithTag(5);
UIColor lightgrey = new UIColor(0.85f, 0.85f, 0.85f, 1.0f);
tableView.BackgroundColor = lightgrey;
if (sat != null)
{
satName.Text = sat.satName;
catalogNumber.Text = string.Format("{0}", sat.catalogNumber);
}
else
System.Console.WriteLine("[ERROR] Satellite was not found for row " + indexPath.Row);
// Set switch state to on when the satellite is already being displayed
if (this.satController.glView.checkForSatelliteExistency(sat.Id))
{
System.Console.WriteLine(sat.satName + "found");
showButton.SetState(true, false);
Satellite sat3D = this.satController.glView.checkForSatelliteOrbit(sat.Id);
if (sat3D.displayOrbit())
orbitButton.SetState(true, false);
}
else // force switch state to off when satellite is not displayed yet
{
showButton.SetState(false, false);
orbitButton.SetState(false, false);
}
favoriteButton.SetState(false, false);
// Bind changing state switches' events in order to display or hide the corresponding satellite
showButton.setData(sat.Id);
favoriteButton.setData(sat.Id);
orbitButton.setData(sat.Id);
if (!this.allocatedCells.Contains(indexPath.Row))
{
showButton.ValueChanged += this.showButtonHandler;
orbitButton.ValueChanged += this.orbitButtonHandler;
}
this.allocatedCells.Add(indexPath.Row);
return cell;
}
}
実際、上記のコードの結果は、tableViewを問題なく上下にスクロールでき、画面から消えたスイッチをクリックしなくなるまで、「SHOWBUTTONHANDLER 」という行を印刷することもできます。スクロール。しかし、リストの一番上に以前に描画され、一番上にスクロールして戻った後に再び表示されたセルの一部であるスイッチをクリックすると、次のエラーが発生します。
[7864:1507] -[UIControlTargetAction BridgeSelector]: unrecognized selector sent to instance 0x14462a70
または次のスタックトレース:
Stacktrace:
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <IL 0x0009f, 0xffffffff>
at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x00042] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:29
at App.Application.Main (string[]) [0x0001b] in App/Main.cs:24
at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff>
Native stacktrace:
0 App 0x0009094c mono_handle_native_sigsegv + 284
1 App 0x00005cd8 mono_sigsegv_signal_handler + 248
2 libSystem.B.dylib 0x90d9c05b _sigtramp + 43
3 ??? 0xffffffff 0x0 + 4294967295
4 UIKit 0x0222e55a -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
5 UIKit 0x022d3b76 -[UIControl sendAction:to:forEvent:] + 66
6 UIKit 0x022d403f -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 503
7 UIKit 0x02425a6c -[_UISwitchInternalView _sendActions] + 121
8 Foundation 0x0173786d __NSFireDelayedPerform + 389
9 CoreFoundation 0x01195966 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
10 CoreFoundation 0x01195407 __CFRunLoopDoTimer + 551
11 CoreFoundation 0x010f87c0 __CFRunLoopRun + 1888
12 CoreFoundation 0x010f7db4 CFRunLoopRunSpecific + 212
13 CoreFoundation 0x010f7ccb CFRunLoopRunInMode + 123
14 GraphicsServices 0x04789879 GSEventRunModal + 207
15 GraphicsServices 0x0478993e GSEventRun + 114
16 UIKit 0x0222ba9b UIApplicationMain + 1175
17 ??? 0x0ebdde65 0x0 + 247324261
18 ??? 0x0ebdc550 0x0 + 247317840
19 ??? 0x0b7f7bac 0x0 + 192904108
20 ??? 0x0b7f7d86 0x0 + 192904582
21 App 0x0000a042 mono_jit_runtime_invoke + 722
22 App 0x00169f4e mono_runtime_invoke + 126
23 App 0x0016e034 mono_runtime_exec_main + 420
24 App 0x00173455 mono_runtime_run_main + 725
25 App 0x00067245 mono_jit_exec + 149
26 App 0x002116a5 main + 2837
27 App 0x00003095 start + 53
28 ??? 0x00000004 0x0 + 4
=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
それで、あなたは解決策のアイデアを持っていますか?スイッチへのデリゲートメソッドが正しく登録されていないようですが、何が問題なのかわかりません。私もこれを使わずに試したので
if (!this.allocatedCells.Contains(indexPath.Row))
行、デリゲートを1回だけ登録するためですが、結果は同じです。セルが画面から消えたときにデリゲートを「登録解除」しようとすると、それを削除する必要がありますか?
私はあなたがアイデアを持っていることを望みます、そしてこれらすべてについてあなたの意見/アドバイス/意見を投稿することを躊躇しないでください。
前もって感謝します !