iOS/Swift: tableView cellForRowAtIndexPath crash - ios

I am experiencing a EXC_BREAKPOINT crash at line 389
386 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
387 let cell = tableView.dequeueReusableCellWithIdentifier("StationsCell", forIndexPath: indexPath)
388 cell.textLabel?.text = self.suggestionStations?[indexPath.row]
389 return cell
390 }
here is the crash report from Crashlytics, happening at 2% of users:
Thread : Crashed: com.apple.main-thread
0 Trenìt! 0x10004a2e4 specialized MasterViewController.tableView(UITableView, cellForRowAtIndexPath : NSIndexPath) -> UITableViewCell (MasterViewController.swift:389)
1 Trenìt! 0x100046488 #objc MasterViewController.tableView(UITableView, cellForRowAtIndexPath : NSIndexPath) -> UITableViewCell (MasterViewController.swift)
2 UIKit 0x18c6b239c -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 544
3 UIKit 0x18c6a6fc4 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2360
4 UIKit 0x18c49cc60 -[UITableView layoutSubviews] + 172
5 UIKit 0x18c3b9874 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 572
6 QuartzCore 0x18bd11d58 -[CALayer layoutSublayers] + 168
7 QuartzCore 0x18bd0c944 CA::Layer::layout_if_needed(CA::Transaction*) + 320
any idea why this happens?

The crash was caused by the suggestionStations array not having a value at the index.
I was not calling ReloadData() on the table when the array was reset to 0. So the the table function was still called in a race condition when the value at the index didn't exist anymore.
The fix was to call ReloadData() also after resetting the array. Otherwise there could have been a check that the index was defined for the array, but this shouldn't be needed if reloadData is properly called each time.

We have had the same issue. This issue is 100% percent reproducible on iOS 10 beta1.
Although hard to believe, we managed to fix the issue by giving a very short cell identifier on storyboard. Like "PhoneContactCell" rename to "PCell".
After some investigation, we kind of think it is a storyboard bug: if a cell prototype is copied and modified then it will probably have this issue.

Make sure that you have definitely set your cell identifier to "StationsCell" in your Main.Storyboard. Select the Cell and go to the Attributes Inspector.
Also add override just before the function, so it should be override func.

Related

UICollectionView crash on performBatchUpdates

I can't figure out what's the reason of this crash?
Incident Identifier: BF4459C1-B97D-448E-AAE0-4DA6A1E4731C
CrashReporter Key: E725A626-A25C-4923-8383-0BC7ECA7DADE
Hardware Model: iPhone6,1
Process: SampleProject [480]
Path: /var/containers/Bundle/Application/458F9694-4BDA-4207-8C90-C2192520F8E2/SampleProject.app/SampleProject
Identifier: com.mydomain.SampleProject
Version: 1.3.0 (1.3.0.36)
Code Type: ARM-64
Parent Process: ??? [1]
Date/Time: 2017-05-17T04:11:03Z
Launch Time: 2017-05-17T04:06:51Z
OS Version: iPhone OS 10.3.1 (14E304)
Report Version: 104
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0xfffffffffffffff8
Crashed Thread: 0
Application Specific Information:
Selector name found in current argument registers: _setLayoutAttributes:atGlobalItemIndex:
Thread 0 Crashed:
0 UIKit 0x000000018de7d38c -[UICollectionViewData _setLayoutAttributes:atGlobalItemIndex:] + 80
1 UIKit 0x000000018de7ac94 __45-[UICollectionViewData validateLayoutInRect:]_block_invoke + 1892
2 UIKit 0x000000018de79f68 -[UICollectionViewData validateLayoutInRect:] + 1492
3 UIKit 0x000000018de8023c -[UICollectionViewData layoutAttributesForElementsInRect:] + 264
4 UIKit 0x000000018de7dbc0 -[UICollectionView _updateVisibleCellsNow:] + 548
5 UIKit 0x000000018dfea058 -[UICollectionView _setupCellAnimations] + 28
6 UIKit 0x000000018dff459c -[UICollectionView _beginUpdates] + 44
7 UIKit 0x000000018e72c8c0 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:] + 256
8 UIKit 0x000000018e72c79c -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:] + 92
9 UIKit 0x000000018e72c720 -[UICollectionView _performBatchUpdates:completion:invalidationContext:] + 80
10 UIKit 0x000000018dff4558 -[UICollectionView performBatchUpdates:completion:] + 60
11 SampleProject 0x000000010002a4b8 -[InvitesDataSource didDeleteDataAtIndexes:loadDataAtIndexes:] (InvitesDataSource.m:50)
12 SampleProject 0x0000000100092f58 -[DialogsController _didReceiveOldestInvites:] (DialogsController.m:311)
13 SampleProject 0x0000000100092500 -[DialogsController _didReceiveOldestDialogs:ofType:] (DialogsController.m:248)
14 SampleProject 0x000000010004aad8 -[DialogsController(Notifications) dialogListDidReceived:] (DialogsController+Notifications.m:94)
Piece of code mentioned in crashlog is quite peaceful:
- (void)didDeleteDataAtIndexes:(NSIndexSet *)deleted loadDataAtIndexes:(NSIndexSet *)loaded {
[self.collectionView performBatchUpdates:^{
[deleted enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
[self.collectionView deleteItemsAtIndexPaths:[self _indexPathsForIndex:idx]];
}];
[loaded enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
[self.collectionView insertItemsAtIndexPaths:[self _indexPathsForIndex:idx]];
}];
} completion:^(BOOL finished) {
[self.collectionView reloadData];
}];
}
This may be happening because you do need to also make sure with collectionViews to delete and insert sections. when you try to insert an item in a section that doesn't exist you will get this crash.
Preform Batch updates doesn't know that you meant to add section X+1 when you insert an item at X+1, X. without you already having added that section in.
make sure to use insert and delete section:
https://developer.apple.com/documentation/uikit/uicollectionview/1618090-insertsections
https://developer.apple.com/documentation/uikit/uicollectionview/1618102-deletesections
To insert, delete, or move a single section or item, you must follow these steps:
Update the data in your data source object.
Call the appropriate method of the collection view to insert or delete the section or item.
It is critical that you update your data source before notifying the collection view of any changes. The collection view methods assume that your data source contains the currently correct data. If it does not, the collection view might receive the wrong set of items from your data source or ask for items that are not there and crash your app.

Could Not load Nib in bundle

I have not been able to upload a Nib to my table view, this problem happened with other application I was working on as well, even though I did have some NIb's files working just fine. I have even reinstall Xcode trying to fix the problem. I am register my Nib as follows
let test = "test"
let cellNib = UINib(nibName: test, bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: test)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: test, for:indexPath) as! testCell //after this function is called I get a crash
return cell
}
This is part of the message I get from the crash, I do not know if is useful.
'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle (loaded)' with name 'tests''
*** First throw call stack:
(
0 CoreFoundation 0x000000010afdab0b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000107b98141 objc_exception_throw + 48
2 CoreFoundation 0x000000010b043625 +[NSException raise:format:] + 197
3 UIKit 0x0000000108b59b24 -[UINib instantiateWithOwner:options:] + 501
4 UIKit 0x00000001088ac567 -[UITableView _dequeueReusableViewOfType:withIdentifier:] + 402
5 UIKit 0x00000001088aca4b -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:] + 71
6 Chaol 0x000000010759ebe9 _TFC5Chaol23QuestionsViewController9tableViewfTCSo11UITableView12cellForRowAtV10Foundation9IndexPath_CSo15UITableViewCell + 153
My .XIB file appears on copy bundle resources.
Perhaps the nib file is not added to your target.
Try those steps:
In Project > Target > Build Phases
expand Copy Bundle Resources
click + button and add the required NIB file.
Clean your build by Shift+Cmd+K, then run.
In your .xib file
click on File Inspector
in Target Membership section, select the target you are using
Also, double check the spelling of your nib name.

Segmentation Fault: 11 - Xcode 6.3

Can't archive
My app runs fine (Xcode 6.3.2, swift based) on Simulator and on multiple devices. But when I try to archive it I get the error Command failed due to signal: Segmentation fault: 11.
Others face same problem
Segmentation Fault 11 when running Swift app
"Command failed due to signal: Segmentation fault: 11" - What is the issue?
Command failed due to signal: Segmentation fault: 11
Root cause?
But it seems that each have different reasons for getting the error.. I am unable to comprehend the error message I am getting. Posted below, any hints or tips would be greatly appreciated!
Error log
0 swift 0x0000000108e5d2b8 llvm::sys::PrintStackTrace(__sFILE*) + 40
1 swift 0x0000000108e5d794 SignalHandler(int) + 452
2 libsystem_platform.dylib 0x00007fff8897bf1a _sigtramp + 26
3 libsystem_platform.dylib 0x00007fff574b7b28 _sigtramp + 3467885608
4 swift 0x0000000108a053f2 swift::serialization::Serializer::writeCrossReference(swift::Decl const*) + 578
5 swift 0x0000000108a0e275 swift::serialization::Serializer::writeAllDeclsAndTypes() + 2181
6 swift 0x0000000108a0f2f8 swift::serialization::Serializer::writeAST(llvm::PointerUnion<swift::Module*, swift::SourceFile*>) + 2600
7 swift 0x0000000108a11960 swift::serialization::Serializer::writeToStream(llvm::raw_ostream&, llvm::PointerUnion<swift::Module*, swift::SourceFile*>, swift::SILModule const*, swift::SerializationOptions const&) + 144
8 swift 0x0000000108a12521 swift::serialize(llvm::PointerUnion<swift::Module*, swift::SourceFile*>, swift::SerializationOptions const&, swift::SILModule const*) + 321
9 swift 0x0000000108746c1a frontend_main(llvm::ArrayRef<char const*>, char const*, void*) + 5514
10 swift 0x00000001087454e6 main + 1814
11 libdyld.dylib 0x00007fff8db235c9 start + 1
12 libdyld.dylib 0x0000000000000080 start + 1917700792
Solved it. Problem was two things:
1) Converting to Double
2) Handling an empty array
Converting to Double
Changed from var lat: Double? = d["lat"].doubleValue to var lat: Double? = Double(d["lat"].doubleValue)
Handling an empty array
Changed from
let brands = d["brands_unfiltered"].arrayValue {
if brands == [] {
// Do nothing (empty)
}
else{
// Do stuff
}
To
if let brands = d["brands_unfiltered"].arrayValue as Array! {
// Do stuff
}
To find the root cause I deactivated larges part of the code until I found what got the archiving not to function. Thereafter the solution was pretty straight forward. Hope this helps someone else struggling with the same error.
I found the code that cause my "Archive" action to fail with this error "Command failed due to signal: Segmentation fault: 11"
When I use the indexPath in the cellForRowAtIndexPath function, I need to put an exclamation mark (i.e indexPath! instead of indexPath). However, I still puzzled by why there is such error if I omit the exclamation mark. Does anyone know the reason?
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!, object: PFObject!) -> PFTableViewCell! {
// code to get cell, etc
let thumbnailImage = self.userPhotos?.getFromCacheOrDownload(username,
circle: team.circle(), delegate: self, indexPath: indexPath!)
cell.userPhotoImageView.image = thumbnailImage
return cell
}

tableView crashes on end up with more than 16 items

This is very confusing.
I have a UITableView, which updates and works fine until it gets more than 16 items then it crashes when trying to endUpdates after calling insertRowsAtIndexPaths.
The NSIndexPaths being added are all valid. -numberOfRowsInSection returns the correct number. It is not throwing an error related to the data set, rather it crashes with
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
when endUpdates is called on the tableView.
The data source is all there, the NSIndexPaths are fine. the code works fine between 0 and 16 rows, but when I add a 17th it crashes. Additionally if I start it with 22 items it works fine, when I add the 23rd it crashes... if I call reload data instead of doing the update and insert process it works fine, so it's nothing to do with the data itself, and it shouldn't be anything to do with how I'm inserting the rows since it works through 16...
I'm completely perplexed. Here is my update method. It is being called on the main thread at all times.
- (void)updateConversation:(NSNotification*)notification
{
NSDictionary *updateInfo = [notification userInfo];
//NSLog(#"Got update %#", updateInfo);
if ([[updateInfo objectForKey:#"success"] integerValue] == YES) {
[self updateConversationUI];
int addedStatementCount = [[updateInfo objectForKey:#"addedStatementCount"] intValue];
if (addedStatementCount > 0) {
//[self.tableView reloadData];
[self.tableView beginUpdates];
int previousStatmentCount = [[updateInfo objectForKey:#"previousStatmentCount"] intValue];
NSLog(#"owner %i, Was %i, now %i, change of %i", self.owner, previousStatmentCount, (int)self.conversation.statements.count, addedStatementCount);
NSMutableArray *rowPaths = [[NSMutableArray alloc] init];
for (int i = previousStatmentCount; i < previousStatmentCount + addedStatementCount; i++) {
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
[rowPaths addObject:path];
}
[self.tableView insertRowsAtIndexPaths:rowPaths withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:[rowPaths lastObject] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
}
The rest of the crash past [self.tableView endUpdates] is UITableView
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(
0 CoreFoundation 0x000000010189b795 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001015fe991 objc_exception_throw + 43
2 CoreFoundation 0x0000000101852564 -[__NSArrayM insertObject:atIndex:] + 820
3 UIKit 0x0000000100317900 __46-[UITableView _updateWithItems:updateSupport:]_block_invoke691 + 173
4 UIKit 0x00000001002b5daf +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 460
5 UIKit 0x00000001002b6004 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 57
6 UIKit 0x00000001003174cb -[UITableView _updateWithItems:updateSupport:] + 2632
7 UIKit 0x0000000100312b18 -[UITableView _endCellAnimationsWithContext:] + 11615
8 Dev App 0x0000000100006036 -[ConversationViewController updateConversation:] + 998
9 CoreFoundation 0x00000001018f121c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
10 CoreFoundation 0x000000010185370d _CFXNotificationPost + 2381
11 Dev App 0x00000001000055ac -[ConversationManager postNotification:] + 92
12 Foundation 0x0000000101204557 __NSThreadPerformPerform + 227
13 CoreFoundation 0x000000010182aec1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
14 CoreFoundation 0x000000010182a792 __CFRunLoopDoSources0 + 242
15 CoreFoundation 0x000000010184661f __CFRunLoopRun + 767
16 CoreFoundation 0x0000000101845f33 CFRunLoopRunSpecific + 467
17 GraphicsServices 0x00000001039a23a0 GSEventRunModal + 161
18 UIKit 0x0000000100261043 UIApplicationMain + 1010
19 Dev App 0x0000000100003613 main + 115
20 libdyld.dylib 0x0000000101f2a5fd start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
This seems like a bug in the OS, the stack would indicate that it's something to do with the animation block but it happens no matter what I set the animation to, including none.
And to re-state. This works through 16 items, then inserting items past that causes a crash. It is also called at initial setup to load data, and it will load any number of items there, including well over 16. But when called again, purely as an update from 16 or more to something higher it will crash.
Most bizarre issue I've yet to encounter with table views...
under iOS 7 on device and simulator, latest Xcode for reference.
It seems that the problem is caused by my call of scrollToRowAtIndexPath (even though it crashes before it gets there...) combined with implementing tableView:estimatedHeightForRowAtIndexPath: by removing the row height estimate the crash went away... still seems like a bug in the animation system for tables to me. Thankfully I don't need the estimated row height, I had forgotten I had implemented it (trying to play nice by iOS 7 bites me again).
Place strategic breakpoints when you are incrementing the statement count, go through the loop of adding the rows as many times as you need to, and locate the statement that it's causing the crash, at that moment take a look at your objects and look for nil values as the error you are having it's trying to insert a nil object(or un-existent) from an Array.
I would personally recommend you to go through this loop entirely while keeping an exe for the path and previous statement count .
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
in my case the tableView:heightForHeaderInSection: method has been missing,
hadn't implemented the tableView:estimatedHeightForRowAtIndexPath method so this also could be solving the problem if you aren't using tableView:estimatedHeightForRowAtIndexPath:
Your problem is that you don't update the dataSource the tableView is using.
if you insert a row, you need to insert the appropriate object to the array the tableView is using.
Goodluck!

Issue with event handler in monotouch button

I have customized my table view cell accessory with button. Everything went fine until event handler.
Here is my code.
[EDIT]
public class ProductTableSource: UITableViewSource
{
protected List<Product> tableItems = new List<Product> ();
protected string cellIdentifier = "producdetailscell";
private RootViewController controller;
protected Transaction transaction;
public UIButton addItemButton;
public UIImage Image;
public ProductTableSource (List<Product> items, RootViewController controller)
{
this.tableItems = items;
this.controller = controller;
Image = UIImage.FromFile ("Images/plus.png");
addItemButton = UIButton.FromType(UIButtonType.Custom);
var buttonFrame = new RectangleF (0f, 0f, Image.Size.Width, Image.Size.Height);
addItemButton.Frame = buttonFrame;
addItemButton.SetImage(Image, UIControlState.Normal);
addItemButton.TouchUpInside += delegate {
Console.WriteLine ("Touched");
};
}
public void setTableItem (List<Product> tableItems)
{
this.tableItems = tableItems;
}
/// <summary>
/// Called by the TableView to determine how many cells to create for that particular section.
/// </summary>
public override int RowsInSection (UITableView tableview, int section)
{
return tableItems.Count;
}
/// <summary>
/// Called when a row is touched
/// </summary>
public override void AccessoryButtonTapped (UITableView tableView, NSIndexPath indexPath)
{
var prod = controller.Productdetails[indexPath.Row];
Double amount = 1*prod.SellingPriceA;
transaction = new Transaction();
transaction.SetTransaction(controller.CustomerID, prod.ID, prod.Description1,1, prod.SellingPriceA,0.0,amount);
controller.UpdateOrderedItemsTableView();
}
/// <summary>
/// Called by the TableView to get the actual UITableViewCell to render for the particular row
/// </summary>
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
// request a recycled cell to save memory
UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);
// if there are no cells to reuse, crate a new one
if (cell == null) {
cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier);
}
var cust = controller.Productdetails [indexPath.Row];
cell.TextLabel.Text = cust.Description1;
cell.AccessoryView = this.controller.addItemButton;
return cell;
}
}
Here is Error I am getting. Not sure what is going on. Perhaps I used inappropriate functions. Please suggestion me!!!
**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) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at SalesOrder.Application.Main (string[]) [0x00000] in /Users/Mac/Projects/SalesOrderPolarisnet/SalesOrder/Main.cs:17
at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff>
Native stacktrace:
0 SalesOrder 0x000908cc mono_handle_native_sigsegv + 284
1 SalesOrder 0x000056f8 mono_sigsegv_signal_handler + 248
2 libsystem_c.dylib 0x9613559b _sigtramp + 43
3 ??? 0xffffffff 0x0 + 4294967295
4 UIKit 0x022620e6 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
5 UIKit 0x02308ade -[UIControl sendAction:to:forEvent:] + 66
6 UIKit 0x02308fa7 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 503
7 UIKit 0x02307d8a -[UIControl touchesBegan:withEvent:] + 264
8 UIKit 0x02523a1a _UIGestureRecognizerUpdate + 6725
9 CoreFoundation 0x011b099e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
10 CoreFoundation 0x01147640 __CFRunLoopDoObservers + 384
11 CoreFoundation 0x011134c6 __CFRunLoopRun + 1174
12 CoreFoundation 0x01112d84 CFRunLoopRunSpecific + 212
13 CoreFoundation 0x01112c9b CFRunLoopRunInMode + 123
14 GraphicsServices 0x048307d8 GSEventRunModal + 190
15 GraphicsServices 0x0483088a GSEventRun + 103
16 UIKit 0x0225f626 UIApplicationMain + 1163
17 ??? 0x0d4d41f4 0x0 + 223166964
18 ??? 0x0d4d2f50 0x0 + 223162192
19 ??? 0x0d4d27c0 0x0 + 223160256
20 ??? 0x0d4d284f 0x0 + 223160399
21 SalesOrder 0x00009ab2 mono_jit_runtime_invoke + 722
22 SalesOrder 0x0016b34e mono_runtime_invoke + 126
23 SalesOrder 0x0016f4d4 mono_runtime_exec_main + 420
24 SalesOrder 0x001748c5 mono_runtime_run_main + 725
25 SalesOrder 0x00066cb5 mono_jit_exec + 149
26 SalesOrder 0x00203911 main + 2209
27 SalesOrder 0x00002ab5 start + 53
=================================================================
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.
=================================================================**
When your GetCell method returns the cell instance no longer has any managed reference. At this point the GC is able to collect it.
However the native parts of your UITableViewCell still exists (they are referenced natively) so it will look fine - but when you use the event handler it tries to get back to managed code... and that does not exists anymore (and it will crash).
There's a few ways to deal with this. A simple one is to keep a reference to each cell you create, e.g. add them to a static List<UITableViewCell>. The GC won't be able to collect them so the event handler will work later.
However your code could be better is re-using the cells. Right now you're re-using the UITableViewCell but not it's content, i.e. you're always creating UIImage and a UIButton. You could easily share them (at least the UIImage) and save memory. You could also only keep a reference to the button (not the whole cell) and save memory while fixing your problem.
EDIT : This is how this should looks like this:
static UIImage shared_image = UIImage.FromFile ("Images/plus.png");
static List<UITableViewCell> cells = new List<UITableViewCell> ();
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);
if (cell == null) {
// create a cell that will be reused (some initialization steps skipped)
cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier);
var addItemButton = UIButton.FromType (UIButtonType.Custom);
// the same image can be shared in all cells to save memory
addItemButton.SetImage (shared_image, UIControlState.Normal);
addItemButton.TouchUpInside += delegate {
Console.WriteLine ("Touched");
};
cell.AccessoryView = addItemButton;
// keep a reference to the cells so they won't be GC'ed
/// that will ensure you can call back (event handler) into the managed instance
cells.Add (cell);
}
// customize the cell - you should not be adding elements here
// otherwise they will be added each time the cell is shown (not created)
cell.TextLabel.Text = indexPath.Row.ToString ();
return cell;
}
It is possible that Mono's GC collect and dispose your UIButtons since they're declared as local variables. I recommend you to subclass UITableViewCell, include UIButton to it and then use that class in GetCell.
BTW, it's better to use TouchUpInside instead of TouchDown event.

Resources