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.
Related
I am getting "The object passed of type Class.TableViewDataSource does not derive from NSObject" error when I do the following I am trying to set the datasource of a UITableView.
viewdidload {
tableView.DataSource = new TableViewDataSource(al);
}
class TableViewDataSource : IUITableViewDataSource
{
public ArrayList listOfSellers
{
get;
set;
}
public TableViewDataSource(ArrayList al) {
listOfSellers = al;
}
public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = (SellerCell)tableView.DequeueReusableCell("cell", indexPath);
cell.seller.Text = (string)listOfSellers[indexPath.Row];
return cell;
}
public nint RowsInSection(UITableView tableView, nint section)
{
return listOfSellers.Count;
}
}
Any ideas why that might be.
If the class derives from interface, you have to implement all the method defined in its parent interface.
Here the method in INativeObject , IDisposable is also needed to implement.
public class TableViewDataSource : IUITableViewDataSource
{
public IntPtr Handle { get; }
public void Dispose()
{
}
}
However, in general we use UITableViewDataSource instead . It derives from IUITableViewDataSource , we just need to override the method inside it .
public class TableViewDataSource : UITableViewDataSource
{
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = (SellerCell)tableView.DequeueReusableCell("cell", indexPath);
cell.seller.Text = (string)listOfSellers[indexPath.Row];
return cell;
}
public override nint RowsInSection(UITableView tableView, nint section)
{
return listOfSellers.Count;
}
}
I try to manage an UICollectionView inside an UIControllerView in Xamarin.iOS.
I tried many things, like this : https://developer.xamarin.com/guides/ios/tvos/user-interface/collection-views/ or this : https://www.youtube.com/watch?v=W4H9uLjoEjM
Finally, I followed this tutorial : https://forums.xamarin.com/discussion/11274/how-to-setup-uicollectionview-datasource
But I'm still blocked. My App crash when it tries to display the UIViewController with this error : [Gotago_iOS_CollectionViewSource_ViewSourceListProgram collectionView:cellForItemAtIndexPath:]: unrecognized selector sent to instance 0x7af49db0'
Here is my code... Any help please ?
public partial class ViewControllerListProgram : UIViewController
{
private ViewSourceListProgram m_viewSource;
public ViewControllerListProgram(IntPtr handle)
: base(handle)
{
}
public override async void ViewDidLoad()
{
base.ViewDidLoad();
AppDelegate.CurrentViewController = this;
ApiController_GetListConseilCircuit apiCtrl = new ApiController_GetListConseilCircuit();
m_collectionView.RegisterClassForCell(typeof(CellListProgram), CellListProgram.Id);
m_viewSource = new ViewSourceListProgram(await apiCtrl.OnlineGetListConseilCircuit());
m_collectionView.Source = m_viewSource;
}
}
public class ViewSourceListProgram : UICollectionViewSource
{
public List<ApiController_GetListConseilCircuit.ConseilCircuit> m_lsCircuits;
public ViewSourceListProgram(List<ApiController_GetListConseilCircuit.ConseilCircuit> lsCircuits)
{
m_lsCircuits = lsCircuits;
}
public override nint NumberOfSections(UICollectionView collectionView)
{
return 1;
}
public override nint GetItemsCount(UICollectionView collectionView, nint section)
{
return m_lsCircuits.Count;
}
public override bool ShouldHighlightItem(UICollectionView collectionView, Foundation.NSIndexPath indexPath)
{
return true;
}
public override void ItemHighlighted(UICollectionView collectionView, Foundation.NSIndexPath indexPath)
{
CellListProgram cell = (CellListProgram)collectionView.CellForItem(indexPath);
Toast.MakeText("Cell highlighted", Toast.LENGTH_LONG).Show();
}
public override void ItemUnhighlighted(UICollectionView collectionView, Foundation.NSIndexPath indexPath)
{
CellListProgram cell = (CellListProgram)collectionView.CellForItem(indexPath);
Toast.MakeText("Cell unhighlighted", Toast.LENGTH_LONG).Show();
}
public UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
{
CellListProgram cell = (CellListProgram)collectionView.DequeueReusableCell(CellListProgram.Id, indexPath);
ApiController_GetListConseilCircuit.ConseilCircuit circuitOrProgram = m_lsCircuits[indexPath.Row];
return cell;
}
}
public partial class CellListProgram : UICollectionViewCell
{
public static readonly NSString Id = new NSString("programCell");
public CellListProgram (IntPtr handle) : base (handle)
{
}
}
Ok... After a few hours of horrible search, I found my error.
I forgot the "override" keyword here :
public UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
Should be
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
argh
Now, everything is Ok ! No crash, and user's actions are well triggered
I have a TableView which is on a normal View, which is on a ViewController.
I have a Class called TableViewController and i want the TableView to use this Class. However, it doesnt enter the TableViewController Class. And yes, i set the property "class" to TableViewController.
My code (TableViewController.cs)
using Foundation;
using System;
using System.Collections.Generic;
using UIKit;
namespace Blogger
{
public partial class TableViewController : UITableView
{
public List<String> Tests { get; set; }
public TableViewController(IntPtr handle) : base(handle)
{
Tests.Add("Jörg");
Tests.Add("Carsten");
}
[Export("numberOfSectionsInTableView:")]
public int NumberOfSections(UITableView tableView)
{
return 1;
}
[Export("tableView:numberOfRowsInSection:")]
public nint RowsInSection(UITableView tableview, nint section)
{
return (nint)Tests.Count;
}
[Export("tableView:titleForHeaderInSection:")]
public string TitleForHeader(UITableView tableView, int section)
{
return "Header";
}
[Export("tableView:didSelectRowAtIndexPath:")]
public void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
}
[Export("tableView:cellForRowAtIndexPath:")]
public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = new UITableViewCell();
cell.TextLabel.Text = Tests[indexPath.Row];
return cell;
}
}
}
I'm an absolute beginner at iOS.
I want to provide swipe-left actions on a table but even though i am setting a proper delegate subclass the EditActionsForRow method is never called on it.
Here's my code:
using System;
using UIKit;
using Foundation;
using System.Linq;
using System.Diagnostics;
namespace Tasky {
public partial class TaskyViewController : UIViewController {
TasksRepository tasksRepository;
TaskItemViewSource tasksViewSource;
public TaskyViewController (IntPtr handle) : base (handle) {
tasksRepository = new TasksRepository ();
tasksViewSource = new TaskItemViewSource ();
tasksViewSource.Data = new TaskItem[0];
tasksViewSource.DeleteClicked += HandleTaskDeleteClicked;
}
public override void ViewDidLoad () {
base.ViewDidLoad ();
TasksTable.Delegate = tasksViewSource;
TasksTable.Source = tasksViewSource;
}
public async override void ViewDidAppear (bool animated) {
base.ViewDidAppear (animated);
var tasks = await tasksRepository.GetAllTasksAsync ();
tasksViewSource.Data = tasks.ToArray ();
TasksTable.ReloadData ();
}
async void HandleTaskDeleteClicked (object sender, NSIndexPath e) {
await tasksRepository.DeleteTaskAsync (tasksViewSource.Data [e.Row]);
TasksTable.ReloadData ();
}
}
public class TaskItemViewSource : UITableViewSource, IUITableViewDelegate {
public TaskItem[] Data { get; set; }
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) {
var task = Data [indexPath.Row];
UITableViewCellStyle cellStyle;
if (String.IsNullOrEmpty (task.Description)) {
cellStyle = UITableViewCellStyle.Default;
} else {
cellStyle = UITableViewCellStyle.Subtitle;
}
var taskCell = new UITableViewCell (cellStyle, "TaskCell");
taskCell.TextLabel.Text = Data [indexPath.Row].Title;
if (!String.IsNullOrEmpty (task.Description)) {
taskCell.DetailTextLabel.Text = Data [indexPath.Row].Description;
}
return taskCell;
}
public override nint RowsInSection (UITableView tableView, nint section) {
return Data.Length;
}
public override void RowSelected (UITableView tableView, NSIndexPath indexPath) {
Debug.WriteLine ("Deselected row #" + indexPath.Row);
tableView.DeselectRow (indexPath, true);
}
public event EventHandler<NSIndexPath> DeleteClicked;
public override UITableViewRowAction[] EditActionsForRow (UITableView tableView, NSIndexPath indexPath) {
Debug.WriteLine ("Inflating edit actions...");
var deleteButton = UITableViewRowAction.Create (
UITableViewRowActionStyle.Destructive,
"Delete",
(action, index) => {
if (DeleteClicked != null) {
DeleteClicked (this, index);
}
});
return new [] { deleteButton };
}
}
}
EDIT:
I managed to fuse the delegate and the view source with Jason's remark, deselecting is now working fine.
Xamarin's TableSource combines two native iOS concepts, the DataSource and the Delegate. Xamarin also provides mappings to the DataSource and Delegate classes. However, you should not mix TableSource with DataSource and Delegate.
From Xamarin's TableView docs:
If you are looking at Objective-C code or documentation, be aware that
Xamarin.iOS aggregates the UITableViewDelegate protocol and
UITableViewDataSource class into this one class. There is no
comparable UITableViewSource class or protocol in Objective-C.
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)