Exception while launching my iOS Xamarin App - c#

I'm faced with a problem with my iOS Xamarin App.
Whenever I try to add a tableView in one of my views with the Storyboard, and I launch my app I have always the same error.
Foundation.MonoTouchException: Objective-C exception thrown. Name:
NSInvalidArgumentException Reason: -[TableSource initWithCoder:]:
unrecognized selector sent to instance 0x17d6a620
Here is my TableSource code:
using Foundation;
using System;
using UIKit;
namespace SmartTransportNatif.iOS2
{
public partial class TableSource : UITableViewSource
{
protected string[] tableItems;
protected string cellIdentifier = "TableCell";
HomeTableController home;
public TableSource (IntPtr handle) : base (handle)
{
}
public TableSource (string[] items, HomeTableController home)
{
this.home = home;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return tableItems.Length;
}
/// <summary>
/// Called when a row is touched
/// </summary>
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
UIAlertController okAlertController = UIAlertController.Create("Row Selected", tableItems[indexPath.Row], UIAlertControllerStyle.Alert);
okAlertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
home.PresentViewController(okAlertController, true, null);
tableView.DeselectRow(indexPath, true);
}
/// <summary>
/// Called by the TableView to get the actual UITableViewCell to render for the particular row
/// </summary>
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
// request a recycled cell to save memory
UITableViewCell cell = tableView.DequeueReusableCell(cellIdentifier);
// if there are no cells to reuse, create a new one
if (cell == null)
cell = new UITableViewCell(UITableViewCellStyle.Default, cellIdentifier);
cell.TextLabel.Text = tableItems[indexPath.Row];
return cell;
}
}
}
Here is my storyboard:
Here are the properties of my Tableview in the HomeTableController:
Does someone know what is missing or wrong?

Related

Selector in UITableViewCell in Xamarin

I need the UIMenuItem to call a method inside the UITableViewCell. Something similar is possible in swift as explained here: https://stackoverflow.com/a/31358474/202179 .
At the moment I am only able to call the method inside the UIViewController from the UIMenuItem if I add an Export attribute to the method.
There is some trick in the export of this method in the cell, but I have failed to find it till now. I would expect this code to work, but it doesn't:
[Register("CustomCell")]
public class CustomCell : UITableViewCell
{
public CustomCell(IntPtr intPtr) : base(intPtr)
{
var menuItem = new UIMenuItem("Menu Item", new ObjCRuntime.Selector("CustomCell.SeekSelectedText"));
UIMenuController.SharedMenuController.MenuItems = new UIMenuItem[] { menuItem };
UIMenuController.SharedMenuController.Update();
}
[Export("SeekSelectedText")]
void SeekSelectedText()
{
//do something
}
}
As said just quoting a different selector inside the UIViewController works, so the problem is that this selector doesn't appear to be recognized whatever I try.
Here is my test and the custom UIMenuItem works fine.
First, define a custom cell class which inherits UITableViewCell
class MyCell: UITableViewCell
{
public MyCell(UITableViewCellStyle style, string reuseIdentifier):base(style, reuseIdentifier)
{
}
[Export("custom")]
void Custom()
{
//do something
Console.WriteLine("custom pop up");
}
public override bool CanPerform(Selector action, NSObject withSender)
{
if (action == new Selector("custom"))
return true;
else
return false;
}
}
Second, set the source of your UITableView
class MyTableViewSource : UITableViewSource
{
int i = 0;
// create custom cell
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
string cellStr = "cell";
MyCell cell = (MyCell)tableView.DequeueReusableCell(cellStr);
if (cell == null)
{
cell = new MyCell(UITableViewCellStyle.Subtitle, cellStr);
cell.TextLabel.Text = $"User Name {i}";
cell.DetailTextLabel.Text = $"details here... {i++}";
}
return cell;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return 10;
}
}
Then override the realted methods(e.g., ShouldShowMenu, CanPerformAction).
class MyTableViewDelegate : UITableViewDelegate
{
public override bool ShouldShowMenu(UITableView tableView, NSIndexPath rowAtindexPath)
{
return true;
}
public override bool CanPerformAction(UITableView tableView, Selector action, NSIndexPath indexPath, NSObject sender)
{
return true;
}
public override void PerformAction(UITableView tableView, Selector action, NSIndexPath indexPath, NSObject sender)
{
}
public override bool ShouldHighlightRow(UITableView tableView, NSIndexPath rowIndexPath)
{
return true;
}
}
Last, don't foget to add custom MenuItem to your UITableViewCell.
UIMenuController.SharedMenuController.MenuItems = new UIMenuItem[] {
new UIMenuItem ("Custom", new Selector ("custom"))
};
Since UICollectionView has similar functions to UITableVIew, you can directly refer to the sample SimpleCollectionView.

UITableViewCell not being rendered correctly

We've created a TableViewController so that a user can enable/disable different notification types. After the initial load, everything is fine until the user scrolls to the bottom then back to the top and the first 1-2 table view cells aren't displaying correctly.
Example:
https://imgur.com/7n2VpTo
Typically deleting and recreating the view controller and xib/cs files fixes this, but was wondering if any one knows the cause of this.
Controller Code:
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return 305;
}
public override nint NumberOfSections(UITableView tableView)
{
return 1;
}
public override nint RowsInSection(UITableView tableView, nint section)
{
return _numRows;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell(Setting.Key) as Setting;
if (cell == null)
{
var values = _settings.Where(s => s.Index == indexPath.Row).FirstOrDefault();
cell = new Setting(values);
var views = NSBundle.MainBundle.LoadNib(Setting.Key, cell, null);
cell = Runtime.GetNSObject(views.ValueAt(0)) as Setting;
}
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
cell?.PopulateData(_settings.Where(s => s.Index == indexPath.Row).FirstOrDefault(), this);
return cell;
}
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
}
Cell Code:
public partial class Setting : UITableViewCell
{
public static readonly NSString Key = new NSString("Setting");
public static readonly UINib Nib;
public SettingModel Values { get; set; }
static Setting()
{ 
Nib = UINib.FromName("Setting", NSBundle.MainBundle);
} 
 
protected Setting(IntPtr handle) : base(handle) { }

public Setting() : base() {

 }

public override void LayoutSubviews()
{ 
base.LayoutSubviews();
}

public void PopulateData(SettingModel values) 
{
//logic...
}
}
Upgrading to Visual Studio for Mac 8.6.5 resolved the issue.

UITableviewCell GetCell is not being called

I am using Visual Studio Community 2017 for Mac. I have a UITableview named SchoolSchedule. I am setting the Source from a button, but then when I click the button GetCell is not called, however, RowsInSection is called.
Here is my class:
public class ScheduleTableViewSource : UITableViewSource
{
private Schedule[] school;
public ScheduleTableViewSource(Schedule[] school)
{
this.school = school;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = (ScheduleCell) tableView.DequeueReusableCell("cell_id", indexPath);
var school1 = school[indexPath.Row];
cell.Updatecell(school1);
cell.TextLabel.Text = school[indexPath.Row].Site;
return cell;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return school.Length;
}
}
here is my button code :
partial void Get_button_TouchUpInside(UIButton sender)
{
bool check = NetworkInterface.GetIsNetworkAvailable();
if(check)
{
Service1 client = new Service1();
var school = client.CypressRidge("CypressRidge");
SchoolSchedule.Source = new ScheduleTableViewSource(school);
SchoolSchedule.ReloadData();
}
else{
Console.Write("Error no Internet connection");
return;
}
// int stop =0;
}
I have checked and there is data coming in from my service. so that is not the problem. can anyone help?
I had to deleted the table and make a new one.
there a bug in Xamarin.
I had the same problem and I managed to fix it setting up Identifier property of TableView first prototype row - in storyboard
In addition to implementing the IUITableViewDelegate and IUITableViewDataSource interfaces in the .cs file, calling RegisterNibForCellReuse, and assigning the table view's EstimatedRowHeight, it's easy to forget to set the data source and delegate properties of the table view in the XIB.

DequeueReusableCell crashes app on iPhone 4S only

I'm developing an app using Xamarin + Mvvmcross. Currently it's working fine on iPad Mini, iPad 2,3, iPhone 5S and 6. Strangely one of the views is crashing on iPhone 4S running iOS 7.1. All tests were done using real devices.
Here's the crash:
https://gist.github.com/nunohorta/2b84245899e8c0daa116
The code for the table source is this one:
public class MessagesTableSource : MvxStandardTableViewSource
{
UITableView _tableview;
MessagesView _parent;
UILabel messageLabel;
private static readonly NSString MessageCellIdentifier = new NSString("MessageCell");
public MessagesTableSource(UITableView tableView, MessagesView parent) : base(tableView)
{
_tableview = tableView;
_parent = parent;
}
public override nint RowsInSection (UITableView tableview, nint section)
{
return _parent.ViewModel.Messages != null ? _parent.ViewModel.Messages.Count : 0;
}
public override nint NumberOfSections (UITableView tableView)
{
if (_parent.ViewModel.Messages != null && _parent.ViewModel.Messages.Count > 0) {
return 1;
} else {
/*
* Custom View here
*
* */
return 0;
}
}
protected override UITableViewCell GetOrCreateCellFor (UITableView tableView, NSIndexPath indexPath, object item)
{
var cell = (MessageCell)tableView.DequeueReusableCell("MessageCell");
return cell;
}
}
I'm also registering the custom class like this on the viewDidLoad:
tableView.RegisterNibForCellReuse(UINib.FromName("MessageCell", NSBundle.MainBundle), MessageCellIdentifier);
I have no idea why is it crashing just for one device...The crash seems to happen on the UIKit/CoreFoundation.
You may need to register MessageCell Nib to custom MessageCell Class, like in view did load method. Because for very first time it may couldn't found cell with identifier.
tableView.registerNib(UINib(nibName: "CustomOneCell", bundle: nil), forCellReuseIdentifier: "CustomCellOne")
To deque cell with identifier
tableView.dequeueReusableCellWithIdentifier("CustomCellOne", forIndexPath: indexPath) as! CustomOneCell
I hope it may help to resolve issue.

Xamarin custom UITableViewCell throws System NullReferenceException

I'm creating a Xamarin app for iOS and I've added a UITableViewCell to a storyboard to give it my own style. I did add a class to this custom UITableViewCell, namely MainMenuCell. I added two labels to the cell and connected them with the MainMenuCell.h file, resulting in the following code:
MainMenuCell.cs
using System;
using Foundation;
using UIKit;
namespace MyProjectNamespace
{
public partial class MainMenuCell : UITableViewCell
{
public MainMenuCell (IntPtr handle) : base (handle)
{
}
public MainMenuCell () : base ()
{
}
public void SetCellData()
{
projectNameLabel.Text = "Project name";
projectDateLabel.Text = "Project date";
}
}
}
MainMenuCell.h (auto-generated):
using Foundation;
using System.CodeDom.Compiler;
namespace MyProjectNamespace
{
[Register ("MainMenuCell")]
partial class MainMenuCell
{
[Outlet]
UIKit.UILabel projectDateLabel { get; set; }
[Outlet]
UIKit.UILabel projectNameLabel { get; set; }
void ReleaseDesignerOutlets ()
{
if (projectNameLabel != null) {
projectNameLabel.Dispose ();
projectNameLabel = null;
}
if (projectDateLabel != null) {
projectDateLabel.Dispose ();
projectDateLabel = null;
}
}
}
}
Now I have my UITableViewSource here, and I'm trying to initialize the MainMenuCell from the GetCell method:
using System;
using UIKit;
using Foundation;
namespace MyProjectNamespace
{
public class MainMenuSource : UITableViewSource
{
public MainMenuSource ()
{
}
public override nint NumberOfSections (UITableView tableView)
{
return 1;
}
public override string TitleForHeader (UITableView tableView, nint section)
{
return "Projects";
}
public override nint RowsInSection (UITableView tableview, nint section)
{
return 1;
}
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
MainMenuCell cell = new MainMenuCell();
cell.SetCellData ();
return cell;
}
}
}
However, it keeps throwing me a System.NullReferenceException at the line:
projectNameLabel.Text = "Project name";
It says: object reference not set to an instance of an object.
What am I missing here? Any help would be highly appreciated.
You're almost there – instead of creating a new cell by yourself, let iOS do the work and dequeue the result.
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = (MainMenuCell)tableView.DequeueReusableCell("MainMenuCell");
cell.SetCellData();
return cell;
}
Note, that "MainMenuCell" is a identifier for the dynamic prototype cell from the Storyboard, you can name it whatever you want, but it has to be the same withing Storyboard and your Datasource.

Categories

Resources