Monotouch custom UITableViewCell GetCell not initialising new custom view cells - uitableview

I've been foloowing a number of tutorials to put together a custom table view cell using storyboard for a prototype table view.
I'm new to monotouch and managed to get a working solution for standard cell types. Running into issues with custom view cells as I'm unable to initialise a fresh cell in the correct manner. Some old tutorials appear to load a cell nib file but I'm using storyboard with the below code.
Where am I going wrong?
(I would use monotouch dialog but not couldn't figure out a way to add lovely uipickerviews on accessory, etc in a simple manner).
http://docs.xamarin.com/guides/ios/user_interface/tables/part_5_-_using_xcode%2C_interface_builder%2C_and_storyboards
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
// in a Storyboard, Dequeue will ALWAYS return a cell
//*** above comment doesnt seem to hold for custom uitableview cells
UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);
// now set the properties as normal
cell.TextLabel.Text = tableItems[indexPath.Row].Name;
if (tableItems[indexPath.Row].Done)
cell.Accessory = UITableViewCellAccessory.Checkmark;
else
cell.Accessory = UITableViewCellAccessory.None;
return cell;
}
// here's my implementation of GetCell but problem is that I can't seem to generate a new cell
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
_cellIdentifier = "SingleTimeViewCell";
CustomViewCell cell = tableView.DequeueReusableCell (_cellIdentifier) as
// if (cell == null)
// {
// cell = new SingleTimeViewCell();
// }
cell.myCustomProperty = "hello";
return cell;
}
// here's the auto generated CustomViewCell class from Xcode storyboard
public partial class CustomViewCell : UITableViewCell
{
public CustomViewCell () : base() // I added this ctor but it didnt seem to help matters
{
}
public CustomViewCell (IntPtr handle) : base (handle)
{
}
}

It can be done using only storyboards with prototype cells, see this sample from Xamarin forums.
Here is the relevant code (credit to Stephane Cordonnier):
public partial class CustomCellStoryBoardViewController : UIViewController
{
public CustomCellStoryBoardViewController(IntPtr handle) : base (handle)
{
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.MyTableView.DataSource = new MyDataSource();
}
private class MyDataSource : UITableViewDataSource
{
private String[] items = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
public MyDataSource()
{
}
public override int RowsInSection(UITableView tableView, int section)
{
return this.items.Length;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
MyCustomCell cell = (MyCustomCell)tableView.DequeueReusableCell(MyCustomCell.Key);
cell.SetTitle(this.items[indexPath.Row]);
return cell;
}
}
}
The custom cell:
[Register ("MyCustomCell")]
public class MyCustomCell : UITableViewCell
{
[Outlet]
MonoTouch.UIKit.UILabel TitleLabel { get; set; }
public static readonly NSString Key = new NSString("MyCustomCell");
public MyCustomCell(IntPtr handle) : base(handle)
{
}
public void SetTitle(String title)
{
this.TitleLabel.Text = title;
}
}
Make sure you have set the custom cell class and identifier to the name of your cell class in the storyboard.

In your .xib file, for that cell, are you using the same cell identifier 'SingleTimeViewCell'. I'm not sure exactly how you've created your custom cell but I know I had what sounds like the same issue.

You cant'd do it with storyboard. Use main storyboard and separate xib files for the cells.

I read so mush non sense about tableview cell and reuse and Xib,
Almost every sample code a found jsute don't reuse properly...
on iOS6 and further the simplest way to do it :
create a new UITABLEVIEWCELL from Xamarin. (let's say MyCustomCell)
in InterfaceBuilder set the Identifier of the cell to the value of MyCustomCell.Key (found the value in MyCsutomCell.cs created by Xamarin Studio)
In your ViewController Register the nib this way :
tableView.RegisterNibForCellReuse (MyCsutomCell.Nib, MyCsutomCell.Key);
then on the GetCell méthode in your dataSource symple dequeue a cell (it will create one if none exists):
MyCsutomCell cell = tableView.DequeueReusableCell (MyCsutomCell.Key) as MyCsutomCell;

Related

Trying to create a Netflix like UI - Project included

Good evening everybody.
Case Study:
Currently I'm working on an tvos application, that needs a Netflix like vertical scroll. I found the following article that explains the approach: https://www.thorntech.com/2015/08/want-your-swift-app-to-scroll-in-two-directions-like-netflix-heres-how/
Problem:
My constructor of the class ("DashboardCollectionView.cs") isn't called, so my cells aren't intialized. In result i receive a view without any collectionviewcells, like the photo below:
Information about code and the project:
I have attached the solution as a zip file. I hope someone can help me. I'm really new on .ios so maybe it can be something easy.
http://www35.zippyshare.com/v/cTJje8WL/file.html
EDIT:
Part of Code
public partial class DashboardCollectionView : UICollectionView
{
public DashboardCollectionView (IntPtr handle) : base (handle)
{
RegisterClassForCell(typeof(DashboardCollectionViewCell), "movieCell");
DataSource = new DashboardCollectionViewDataSource();
Delegate = new DashboardCollectionViewDelegateFlowLayout();
}
}
public partial class DashboardCollectionViewCell : UICollectionViewCell
{
public DashboardCollectionViewCell (IntPtr handle) : base (handle)
{
}
}
public class DashboardCollectionViewDataSource: UIKit.UICollectionViewDataSource
{
public DashboardCollectionViewDataSource()
{
}
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
{
var movieCell = (DashboardCollectionViewCell)collectionView.DequeueReusableCell("movieCell", indexPath);
return movieCell;
}
public override nint GetItemsCount(UICollectionView collectionView, nint section)
{
return 12;
}
public override nint NumberOfSections(UICollectionView collectionView)
{
return 1;
}
}
public class DashboardCollectionViewDelegateFlowLayout : UIKit.UICollectionViewDelegateFlowLayout
{
public DashboardCollectionViewDelegateFlowLayout()
{
}
public override CoreGraphics.CGSize GetSizeForItem(UIKit.UICollectionView collectionView, UIKit.UICollectionViewLayout layout, Foundation.NSIndexPath indexPath)
{
var itemsPerRow = 4;
var hardCodedPadding = 10;
var itemWidth = (collectionView.Bounds.Width / itemsPerRow) - hardCodedPadding;
var itemHeight = collectionView.Bounds.Height - (2 * hardCodedPadding);
return new CoreGraphics.CGSize(itemWidth, itemHeight);
}
}
public partial class DashboardTableViewController : UITableViewController
{
private String[] categories = new String[] { "Kürzlich hinzugefügt", "Beliebt" };
private String cardCellId = "cell";
public DashboardTableViewController(IntPtr handle) : base(handle)
{
}
public override nint NumberOfSections(UITableView tableView)
{
return categories.Length;
}
public override string TitleForHeader(UITableView tableView, nint section)
{
return categories[section];
}
public override nint RowsInSection(UITableView tableView, nint section)
{
return 1;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell(cardCellId, indexPath);
return cell;
}
}
The problem is this part
3. Now for the tricky part — wiring the Collection View’s DataSource and Delegate to the cell. It’s easier if you drag from the Collection View’s Connections Inspector to the Table View Cell within the view hierarchy.
I am not sure how to do that using VS story board, you probably need to use XCode. You kind of try to do it programmatically but that doesn't work.
So if working with XCode is not an option you can trick this part and give to your DashboardCollectionView a name to force its creation. But you cannot do that without creating custom class of your "Table View Cell".
You also need to comment out
//RegisterClassForCell(typeof(DashboardCollectionViewCell), "movieCell");
After those 3 steps you should be able to see your cells. I ran it on iOS 9 simulator but couldn't get any scrolling vertical or horizontal but this is a different question.

How do I put a button inside a tableview cell?

I'm new to this, so I have troubles doing that. My goal is too put, like the title said, a button inside a cell. If you want to see my code, so that this could help you to answer this question, here is the code:
using System;
using System.Collections.Generic;
using System.Text;
using Foundation;
using UIKit;
namespace TableView
{
public class TableSource : UITableViewSource
{
string[] tableItems;
string cellIdentifier = "TableCell";
public TableSource (string[] items)
{
tableItems = items;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return tableItems.Length;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
new UIAlertView("Alert", "You selected: " + tableItems[indexPath.Row], null, "Next Site", null).Show();
tableView.DeselectRow(indexPath, true);
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell(cellIdentifier);
if (cell == null)
cell = new UITableViewCell(UITableViewCellStyle.Subtitle, cellIdentifier);
cell.TextLabel.Text = tableItems[indexPath.Row];
if(indexPath.Row > -1)
cell.DetailTextLabel.Text = tableItems[indexPath.Row - 0];
return cell;
}
}
}
Here is the code for ViewController, if this is needed to.
Create a custom TableViewCell and add the button there. Than use that custom TableViewCell in your GetCell method.
class MyButtonTableViewCell : UITableViewCell
{
public UIButton MyButton { get; private set; }
public MyButtonTableViewCell() : base(UITableViewCellStyle.Default, "MyButtonCell")
{
MyButton = new UIButton(UIButtonType.System);
MyButton.Frame = ContentView.Bounds;
MyButton.SetTitle("My Title", UIControlState.Normal);
ContentView.AddSubview(MyButton);
}
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell("MyButtonCell");
if (cell == null)
cell = MyButtonTableViewCell();
return cell;
}
First of all you need to add a tag to the button so that you can see what button is being pressed inside the cellForRowAtIndexPath function like this:
cell.Button.tag = indexPath.row
Then inside an IBAction you can see exactly what row's button was pressed like this:
#IBAction func buttonPressed(sender: AnyObject)
{
let button = sender as! UIButton
let index = NSIndexPath(forRow: button.tag, inSection: 0)
}

Xamarin Table View Crash

I want to use UITableView on XamarinApp.
I tried UITableView example Populating a Table with Data ,but it doesn't work.
When i used this.Add(table); cause crash. When I remove this.Add(table) it's shows empty table.
Please help me...
Here is my code
using Foundation;
using System;
using System.CodeDom.Compiler;
using UIKit;
namespace KUkyuko
{
partial class MyTableViewSource : UITableView
{
public MyTableViewSource(IntPtr handle) : base (handle)
{
var table = this;
string[] tableItems = new string[] {"Vegetables","Fruits","Flower Buds","Legumes","Bulbs","Tubers"};
table.Source = new TableSource(tableItems);
this.Add(table); //this code cause crash
}
}
public class TableSource : UITableViewSource {
string[] TableItems;
string CellIdentifier = "TableCell";
public TableSource (string[] items)
{
TableItems = items;
}
public override nint RowsInSection (UITableView tableview, nint section)
{
return TableItems.Length;
}
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell (CellIdentifier);
string item = TableItems[indexPath.Row];
//---- if there are no cells to reuse, create a new one
if (cell == null)
{ cell = new UITableViewCell (UITableViewCellStyle.Default, CellIdentifier); }
cell.TextLabel.Text = item;
return cell;
}
}
}
Im abit unsure as to what you trying to achieve but
I would change the tableview to a tableViewController like so::
partial class TableViewController : UITableViewController
{
public TableViewController (IntPtr handle) : base (handle)
{
// Register the TableView's data source
string[] tableItems = new string[] {"Vegetables","Fruits","Flower Buds","Legumes","Bulbs","Tubers"};
this.TableView.Source = new TableSource(tableItems);
}
}
public class TableSource : UITableViewSource {
string[] TableItems;
string CellIdentifier = "TableCell";
public TableSource (string[] items)
{
TableItems = items;
}
public override nint RowsInSection (UITableView tableview, nint section)
{
return TableItems.Length;
}
public override nint NumberOfSections (UITableView tableView)
{
// TODO: return the actual number of sections
return 1;
}
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell (CellIdentifier);
string item = TableItems[indexPath.Row];
//---- if there are no cells to reuse, create a new one
if (cell == null)
{ cell = new UITableViewCell (UITableViewCellStyle.Default, CellIdentifier); }
cell.TextLabel.Text = item;
return cell;
}
}
If you are using the table inside a viewController then you need to do this part in your viewController and set up a outlet for the table.
The reason this code crashes as you are adding this to this:
var table = this;
string[] tableItems = new string[] {"Vegetables","Fruits","Flower Buds","Legumes","Bulbs","Tubers"};
table.Source = new TableSource(tableItems);
this.Add(table); //this code cause crash as it is the same as this.Add(this)
Hope this helps!

no suitable method found to override RowsInSection xamarin

class CallHistoryDataSource : UITableViewSource
{
CallHistoryController controller;
public CallHistoryDataSource (CallHistoryController controller)
{
this.controller = controller;
}
public override int RowSelected(UITableView tableView, int section)
{
return controller.PhoneNumbers.Count;
}
//
// Returns a table cell for the row indicated by row property of the NSIndexPath
// This method is called multiple times to populate each row of the table.
// The method automatically uses cells that have scrolled off the screen or creates new ones as necessary.
//
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell (CallHistoryController.callHistoryCellId);
int row = indexPath.Row;
cell.TextLabel.Text = controller.PhoneNumbers [row];
return cell;
}
}
`Helloworld_iOS.CallHistoryController.CallHistoryDataSource.RowSelected(UIKit.UITableView, int)' is marked as an override but no suitable method found to override (CS0115)
Hi I'm trying to make a helloworld application with xamarin monotouch and I'm taking this error.Can anybody help me about this?
Thank you
My guess is that you're using the Unified API.
In which case use this (nint instead of int):
public override nint RowSelected(UITableView tableView, nint section)

How to make use of cell reuse in UITableViewSource in Xamarin?

I have UITableViewSource class which is used for the UISearchDisplayController. In my main table view I have a custom cell which works fine. Now I want to use the custom cell also for the table view of the search results. But I only manage it to display the default style with
public class SearchSource : UITableViewSource
{
static NSString cellIdentifier = new NSString("CustomCell");
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);
if (cell == null)
cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier);
cell.TextLabel.Text = myList [indexPath.Row].Name;
return cell;
}
But here I only have the standard cell and I want my custom cell. The custom cell on the main table view uses the following code:
public partial class TestViewController : UITableViewController
{
static NSString cellIdentifier = new NSString("CustomCell");
public TestViewController (IntPtr handle) : base (handle)
{
TableView.RegisterClassForCellReuse (typeof(CustomCell), cellIdentifier);
}
public class TableSource : UITableViewSource {
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath){
CustomCell cell = (CustomCell)tableView.DequeueReusableCell (cellIdentifier);
cell.UpdateCell(...);
}
}
Here is the constructor of the CustomCell:
public CustomCell (IntPtr handle) : base(handle)
This is how I create the UISearchDisplayController:
// create search controller
searchBar = new UISearchBar (new RectangleF (0, 0, View.Frame.Width, 50)) {
Placeholder = "Enter a search query"
};
searchController = new UISearchDisplayController (searchBar, this);
searchController.Delegate = new SearchDelegate (tableItems);
searchController.SearchResultsSource = new SearchSource (searchController);
this.TableView.TableHeaderView = searchBar;
But everything I try leads to a crash of the app (no reference, cannot dequeue, ...) or there is a constructor mismatch.
How can I use my custom cell for the table view generated by the UISearchDisplayController?
Switching to the new cell reuse pattern since iOS 6 I adapted my SearchSource to
CustomPatientCell cell = (CustomCell)tableView.DequeueReusableCell (cellIdentifier);
and I added the following to my TestViewController:
searchController.SearchResultsTableView.RegisterClassForCellReuse(typeof(CustomCell), cellIdentifier);
I only had to add some methods like GetHeightForRow to my SearchSource to get this thing to work.
Now I have two similar implementations of TableSource and SearchSource - perhaps it is possible to summarize both? I saw from other implementations that methods like numberOfRowsInSection query which table view is currently active. How could I summarize that also?

Resources