我有一个UITableView
,为此我要使用自定义单元格将UIGestureRecognizer
附加到ImageView。识别器可以在tableview的最后一行正常工作,但是如果我尝试在最后一个之前的任何单元格,则应用程序将崩溃,并出现以下错误。我不确定如何调试它,或者实际上是否应该直接向Xamarin提出。
任何帮助表示赞赏。
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Collections.Generic;
namespace gestures
{
public partial class gestureTest : UIViewController
{
#region Private Variables
private bool imageHighlighted = false;
private bool touchStartedInside;
#endregion
public gestureTest () : base ("gestureTest", null)
{
}
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// UIView viewGesture = new UIView ();
//
// viewGesture.Add (tblGesture);
fillTabele ();
// Perform any additional setup after loading the view, typically from a nib.
}
protected void fillTabele( ) {
List<WorkItem> list = new List<WorkItem>();
list.Add (new WorkItem ("soemthing"));
list.Add (new WorkItem ("soemthing else"));
list.Add (new WorkItem ("soemthing other than else"));
UITableView table = new UITableView(View.Bounds); // defaults to Plain style
table.Source = new TableSource(list,"sptring",this);
Add (table);
}
public class WorkItem {
public WorkItem() {}
public WorkItem(string reftitle) {
this.myTitle = reftitle;
}
private string myTitle;
public string title
{
get
{
return myTitle;
}
set
{
myTitle = value;
}
}
}
public class TableSource : UITableViewSource {
protected WorkItem[]
_tableItems; protected string _cellIdentifier = "TableCell";
string vc;
UIImageView img;
UIViewController vController;
UIAlertView alert;
UITapGestureRecognizer gesture = null;
//TaskViewController addTaskController;
public TableSource(List<WorkItem> tblItemGroups, string sprint,UIViewController vCon)
{
this._tableItems = tblItemGroups.ToArray();
this.vc = sprint;
this.vController = vCon;
}
public override int RowsInSection(UITableView tableview, int section)
{
if (_tableItems != null)
{
return this._tableItems.Length;
}
else
{
return 0;
}
}
public override UIView GetViewForHeader(UITableView tableView, int section)
{
return BuildSectionHeaderView(vc.ToString());
}
public static UIView BuildSectionHeaderView(string caption)
{
UIView view = new UIView(new System.Drawing.RectangleF(0, 0, 320, 20));
UILabel label = new UILabel();
label.BackgroundColor = UIColor.Clear;
label.Opaque = false;
label.TextColor = UIColor.Black;
label.Font = UIFont.FromName("Helvetica-Bold", 16f);
label.Frame = new System.Drawing.RectangleF(15, 0, 290, 20);
label.Text = caption;
view.AddSubview(label);
return view;
}
public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return 50f;
}
public override string TitleForHeader(UITableView tableView, int section)
{
return vc.ToString();
}
public static void ClearEmptyTableViewSpacer(UITableView oTableView)
{
UIView oViewSpacerClear = new UIView(new RectangleF(0, 0, oTableView.Frame.Width, 10));
oViewSpacerClear.BackgroundColor = UIColor.Clear;
oTableView.TableFooterView = oViewSpacerClear;
}
public override UITableViewCell GetCell(UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad)
{
tableView.BackgroundView = null;
}
else
{
tableView.BackgroundColor = null;
}
WorkItem wrkitem = _tableItems[indexPath.Row];
UITableViewCell cell = tableView.DequeueReusableCell(this._cellIdentifier);
if (cell == null)
{
cell = new UITableViewCell(UITableViewCellStyle.Default, this._cellIdentifier);
}
NSAction action = () => {
//alert=new UIAlertView("gesture recognized","tap me image tapped @" + gesture.LocationOfTouch (0, img).ToString (),null,"Ok","Cancel");
alert=new UIAlertView("gesture recognized","tap me image tapped @",null,"Ok","Cancel");
alert.Show();
};
cell.TextLabel.Text = wrkitem.title.ToString ();
cell.ImageView.Image = UIImage.FromFile("images/splash-text.png");
cell.ImageView.UserInteractionEnabled = true;
gesture = new UITapGestureRecognizer();
gesture.AddTarget(()=>action());
cell.ImageView.AddGestureRecognizer(gesture);
cell.ImageView.Frame = new RectangleF(10, 14, 5, 5);
cell.TextLabel.Lines = 0;
cell.TextLabel.LineBreakMode = UILineBreakMode.WordWrap;
return cell;
}
}
}
}
错误
mono-rt: Stacktrace:
mono-rt: at <unknown> <0xffffffff>
mono-rt: at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <IL 0x0009f, 0xffffffff>
mono-rt: at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
mono-rt: at gestures.Application.Main (string[]) [0x00008] in /Users/xxxxxx/Projects/gestures/gestures/Main.cs:17
mono-rt: at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff>
mono-rt:
Native stacktrace:
mono-rt:
=================================================================
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.
=================================================================
!-单元格调整
public override UITableViewCell GetCell(UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad)
{
tableView.BackgroundView = null;
}
else
{
tableView.BackgroundColor = null;
}
WorkItem wrkitem = _tableItems[indexPath.Row];
UITableViewCell cell = tableView.DequeueReusableCell(this._cellIdentifier);
if (cell == null)
{
NSAction action = () => {
//alert=new UIAlertView("gesture recognized","tap me image tapped @" + gesture.LocationOfTouch (0, img).ToString (),null,"Ok","Cancel");
alert=new UIAlertView("gesture recognized","tap me image tapped @",null,"Ok","Cancel");
alert.Show();
};
cell = new UITableViewCell(UITableViewCellStyle.Default, this._cellIdentifier);
cell.ImageView.UserInteractionEnabled = true;
gesture = new UITapGestureRecognizer();
gesture.AddTarget(()=>action());
cell.ImageView.AddGestureRecognizer(gesture);
cell.ImageView.Frame = new RectangleF(10, 14, 5, 5);
cell.TextLabel.Lines = 0;
cell.TextLabel.LineBreakMode = UILineBreakMode.WordWrap;
}
cell.TextLabel.Text = wrkitem.title.ToString ();
cell.ImageView.Image = UIImage.FromFile("images/splash-text.png");
return cell;
}//
*new error*
2014-07-04 07:28:57.263 gestures[22619:1303] MonoTouch: Socket error while connecting to MonoDevelop on 127.0.0.1:10000: Connection refused
2014-07-04 07:29:16.139 gestures[22619:80b] -[__NSSetM target]: unrecognized selector sent to instance 0xe6ce030
Unhandled Exception:
MonoTouch.Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[__NSSetM target]: unrecognized selector sent to instance 0xe6ce030
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at gestures.Application.Main (System.String[] args) [0x00008] in /Users/xxxxxx/Projects/gestures/gestures/Main.cs:17
NSInvalidArgumentException: -[__NSSetM target]: unrecognized selector sent to instance 0xe6ce030
0 CoreFoundation 0x0161e5e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x04e898b6 objc_exception_throw + 44
2 CoreFoundation 0x016bb903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x0160e90b ___forwarding___ + 1019
4 CoreFoundation 0x0160e4ee _CF_forwarding_prep_0 + 14
5 UIKit 0x02ccee8c _UIGestureRecognizerSendActions + 230
6 UIKit 0x02ccdb00 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 383
7 UIKit 0x02ccf56d -[UIGestureRecognizer _delayedUpdateGesture] + 60
8 UIKit 0x02cd2acd ___UIGestureRecognizerUpdate_block_invoke + 57
9 UIKit 0x02cd2a4e _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 317
10 UIKit 0x02cc9148 _UIGestureRecognizerUpdate + 199
11 UIKit 0x0299519a -[UIWindow _sendGesturesForEvent:] + 1291
12 UIKit 0x029960ba -[UIWindow sendEvent:] + 1030
13 UIKit 0x02969e86 -[UIApplication sendEvent:] + 242
14 UIKit 0x0295418f _UIApplicationHandleEventQueue + 11421
15 CoreFoundation 0x015a783f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
16 CoreFoundation 0x015a71cb __CFRunLoopDoSources0 + 235
17 CoreFoundation 0x015c429e __CFRunLoopRun + 910
18 CoreFoundation 0x015c3ac3 CFRunLoopRunSpecific + 467
19 CoreFoundation 0x015c38db CFRunLoopRunInMode + 123
20 GraphicsServices 0x060969e2 GSEventRunModal + 192
21 GraphicsServices 0x06096809 GSEventRun + 104
22 UIKit 0x02956d3b UIApplicationMain + 1225
23 ??? 0x127f82ac 0x0 + 310346412
24 ??? 0x127f713c 0x0 + 310341948
25 ??? 0x127f6ec0 0x0 + 310341312
26 ??? 0x127f6f4f 0x0 + 310341455
27 gestures 0x000f655b mono_jit_runtime_invoke + 843
28 gestures 0x00194b5f mono_runtime_invoke + 127
29 gestures 0x0019a671 mono_runtime_exec_main + 401
30 gestures 0x0019a434 mono_runtime_run_main + 628
31 gestures 0x00054ffd mono_jit_exec + 93
32 gestures 0x00235a70 main + 2784
33 gestures 0x00003a15 start + 53
2014-07-04 07:29:16.150 gestures[22619:80b] Unhandled managed exception: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[__NSSetM target]: unrecognized selector sent to instance 0xe6ce030 (MonoTouch.Foundation.MonoTouchException)
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at gestures.Application.Main (System.String[] args) [0x00008] in /Users/seankerr/Projects/gestures/gestures/Main.cs:17
mono-rt:Stacktrace:
mono-rt:
Native stacktrace:
mono-rt: 0 gestures 0x000c4777 mono_handle_native_sigsegv + 327
mono-rt: 1 gestures 0x000cf5ba sigabrt_signal_handler + 122
mono-rt: 2 libsystem_platform.dylib 0x05427deb _sigtramp + 43
mono-rt: 3 ??? 0xffffffff 0x0 + 4294967295
mono-rt: 4 libsystem_sim_c.dylib 0x05144e12 abort + 127
mono-rt: 5 gestures 0x0024db33 monotouch_unhandled_exception_handler + 291
mono-rt: 6 gestures 0x000c4fbb mono_invoke_unhandled_exception_hook + 91
mono-rt: 7 gestures 0x000c3fcc mono_handle_exception_internal + 6620
mono-rt: 8 gestures 0x000c25e9 mono_handle_exception + 41
mono-rt: 9 gestures 0x0005cdd9 mono_x86_throw_exception + 137
mono-rt: 10 ??? 0x0ee30e57 0x0 + 249761367
mono-rt: 11 gestures 0x0023d001 monotouch_exception_handler + 177
mono-rt: 12 CoreFoundation 0x016aea1d __handleUncaughtException + 749
mono-rt: 13 libobjc.A.dylib 0x04e89b5c _ZL15_objc_terminatev + 100
mono-rt: 14 libc++abi.dylib 0x0535df60 _ZSt11__terminatePFvvE + 14
mono-rt: 15 libc++abi.dylib 0x0535db97 __cxa_rethrow + 103
mono-rt: 16 libobjc.A.dylib 0x04e89a57 objc_exception_rethrow + 47
mono-rt: 17 CoreFoundation 0x015c3b55 CFRunLoopRunSpecific + 613
mono-rt: 18 CoreFoundation 0x015c38db CFRunLoopRunInMode + 123
mono-rt: 19 GraphicsServices 0x060969e2 GSEventRunModal + 192
mono-rt: 20 GraphicsServices 0x06096809 GSEventRun + 104
mono-rt: 21 UIKit 0x02956d3b UIApplicationMain + 1225
mono-rt: 22 ??? 0x127f82ac 0x0 + 310346412
mono-rt: 23 ??? 0x127f713c 0x0 + 310341948
mono-rt: 24 ??? 0x127f6ec0 0x0 + 310341312
mono-rt: 25 ??? 0x127f6f4f 0x0 + 310341455
mono-rt: 26 gestures 0x000f655b mono_jit_runtime_invoke + 843
mono-rt: 27 gestures 0x00194b5f mono_runtime_invoke + 127
mono-rt: 28 gestures 0x0019a671 mono_runtime_exec_main + 401
mono-rt: 29 gestures 0x0019a434 mono_runtime_run_main + 628
mono-rt: 30 gestures 0x00054ffd mono_jit_exec + 93
mono-rt: 31 gestures 0x00235a70 main + 2784
mono-rt: 32 gestures 0x00003a15 start + 53
mono-rt:
=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
更新了堆栈跟踪
mono-rt: at <unknown> <0xffffffff>
mono-rt: at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <IL 0x0009f, 0xffffffff>
mono-rt: at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
mono-rt: at gestures.Application.Main (string[]) [0x00008] in /Users/seankerr/Projects/gestures/gestures/Main.cs:17
mono-rt: at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff>
mono-rt:
Native stacktrace:
mono-rt:
=================================================================
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.
=================================================================
最终更新
我接受了@pnavk的建议,并再次使用一个空白项目开始,使用Xamarin网站上的代码创建了基本项目,然后将UIGestureRecognizer添加到了单元格中。
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace gestures
{
public partial class gestureController : UIViewController
{
public gestureController () : base ("gestureController", null)
{
}
UITableView table;
private string _caption = "caption";
static NSString kCellIdentifier = new NSString ("MyIdentifier");
static UIView cellView = new UIView (new RectangleF (325, 0, 320, 568));
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
table = new UITableView (View.Bounds); // defaults to Plain style
string[] tableItems = new string[] { "Vegetables", "Fruits", "Flower Buds", "Legumes", "Bulbs", "Tubers" };
table.Source = new TableSource (tableItems);
Add (table);
cellView.BackgroundColor = UIColor.Blue;
View.Add (cellView);
// Perform any additional setup after loading the view, typically from a nib.
}
public class TableSource : UITableViewSource
{
string[] tableItems;
protected string _cellIdentifier = "TableCell";
public TableSource (string[] items)
{
tableItems = items;
}
public override int RowsInSection (UITableView tableview, int section)
{
return tableItems.Length;
}
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
CustomVegeCell cell = tableView.DequeueReusableCell (kCellIdentifier) as CustomVegeCell;
if (cell == null)
cell = new CustomVegeCell (kCellIdentifier);
cell.UpdateCell (tableItems [indexPath.Row], tableItems [indexPath.Row], UIImage.FromFile ("splash-text.png"), cellView);
return cell;
}
}
}
}
最佳答案
我将对您的代码进行以下更改:
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad)
{
tableView.BackgroundView = null;
}
else
{
tableView.BackgroundColor = null;
}
这应该移出GetCell并移到ViewDidLoad或ViewWillAppear中。 GetCell方法被反复调用(当您滚动或重新加载数据时)和(我可能是不正确的),但是此代码看起来好像不需要多次调用。您还应该如前所述,在ViewDidLoad或ViewWillAppear中将图像初始化为全局变量(例如myImage)一次,然后对其进行分配,而不是一遍又一遍地加载它。
现在,您可以创建一个自定义UITableViewCell并在自定义单元格的AwakeFromNib方法中的ImageView上实现该手势识别器,而不是每次在GetCell中设置手势识别器:
namespace gestures
{
public partial class gestureTestCell : UITableViewCell
{
public static string _cellIdentifier = "gestureTestCell"; // whatever you name it in Interface Builder
public gestureTestCell () : base ()
{
}
public gestureTestCell (IntPtr handle) : base (handle)
{
}
protected override void Dispose (bool disposing)
{
myImageView.RemoveGestureRecognizer(gesture)
base.Dispose (disposing);
}
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
var gesture = new UITapGestureRecognizer (HandleTapGesture);
myImageView.AddGestureRecognizer (gesture);
}
public override void LayoutSubviews ()
{
base.LayoutSubviews ();
myImageView.UserInteractionEnabled = true;
myImageView.Frame = new RectangleF(10, 14, 5, 5);
myTextLabel.Lines = 0;
myTextLabel.LineBreakMode = UILineBreakMode.WordWrap;
}
void HandleTapGesture (UITapGestureRecognizer gesture)
{
var alert = new UIAlertView("gesture recognized","tap me image tapped @",null,"Ok","Cancel");
alert.Show();
}
public override void PrepareForReuse ()
{
base.PrepareForReuse ();
}
public void SetupCell(string text, UIImage image)
{
myImageView.Image = image;
myTextLabel.Text = text;
}
}
}
现在,您的
GetCell
方法可以类似于:public override UITableViewCell GetCell(UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
gestureTestCell cell = tableView.DequeueReusableCell(gestureTestCell._cellIdentifier) ?? new gestureTestCell();
cell.SetupCell(_tableItems[indexPath.Row].ToString(), myImage);
return cell;
}
关于ios - SIGSEGV错误IOS-UITableView上的UiGestureRecognizer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24542205/