I have a UITableView set up with GetCell, RowsInSection, and other methods required for my UITableView. Here is my code:
using UIKit;
...
namespace ...
{
public partial class (className) : UIViewController, IUITextFieldDelegate, IUITableViewDataSource, IUITableViewDelegate
bool test = false;
public override void ViewDidLoad()
{
base.ViewDidLoad();
table.ReloadData();
table.DataSource = this;
table.Delegate = this;
test = true;
}
...
public nint RowsInSection(UITableView tableview, nint section)
{
return 2;
}
public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell("cell") as Cell;
bool selected = test;
cell.Setup(selected);
return cell;
}
}
What I attempt to do is checking a changed value of a variable while setting up the cell in GetCell. However, it seems that the GetCell method ignores the changed value of the variable test, so my question is how do I access the variable after the change in ViewDidLoad.
Call table.ReloadData(); after modifying test , because reloadData is used to trigger all the methods in the delegate including GetCell .
table.DataSource = this;
table.Delegate = this;
test = true;
table.ReloadData();
Your code is not for cell reuse , pls refer to the correct way here .
//register
table.RegisterClassForCellReuse (typeof(Cell), "cell");
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
//cell reuse
var cell = (Cell) tableView.DequeueReusableCell ("cell", indexPath);
if (cell == null) cell = new Cell("cell");
bool selected = test;
cell.Setup(selected);
return cell;
}
Related
I have Tableview with longpress cell.
I can't read the data inside the cell which have been long pressed.
rowselected() method is not the right way because I must select cell first. I didn't want to select cell first.
This is my table adapter class:
internal class AbsetAdapterClass : UITableViewSource
{
private List<benood2.AbsentClass> absentList;
public AbsetAdapterClass(List<benood2.AbsentClass> absentList)
{
this.absentList = absentList;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = (TableClass)tableView.DequeueReusableCell("cell_id", indexPath);
var AbsentDay = absentList[indexPath.Row];
var longPressGesture = new UILongPressGestureRecognizer(LongPressMethod);
cell.AddGestureRecognizer(longPressGesture);
cell.UpdateCell(AbsentDay);
return cell;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return absentList.Count;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
PublicClass.ReadCellValue = "";
var GetCellValue = absentList[indexPath.Row].BandValue;
tableView.DeselectRow(indexPath, true);
}
void LongPressMethod(UILongPressGestureRecognizer gestureRecognizer)
{
if (gestureRecognizer.State == UIGestureRecognizerState.Began)
{
Toast.MakeToast("I want to read the cell data ").SetTitle(PublicClass.ReadCellID.ToString()).SetDuration(ToastDuration.Regular).Show();
}
}
}
I can't get the long press cell data
You could attach LongPressGesture to the UITableView instead of the UITableViewCell.
You could try the following code (Note: i made my demo based on the Xamarin.iOS official samples):
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
table = new UITableView(new CGRect(0, 0, width, height));
...
// add longPressGesture to the tableView
var longPressGesture = new UILongPressGestureRecognizer(LongPressMethod);
table.AddGestureRecognizer(longPressGesture);
...
}
Then for LongPressMethod:
void LongPressMethod(UILongPressGestureRecognizer gestureRecognizer)
{
var p = gestureRecognizer.LocationInView(table);
var indexPath = table.IndexPathForRowAtPoint(p);
if (indexPath == null)
{
Console.WriteLine("Long press on table view but not on a row.");
}
else if (gestureRecognizer.State == UIGestureRecognizerState.Began)
{
Console.WriteLine("Long press on {0} row", indexPath.Row);
//you could get the selectedItem through the Row index
}
}
For more info, you could refer to Working with Tables and Cells in Xamarin.iOS.
Hope it works for you.
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)
}
I want to add a footer view to a UITableView that shows a UIProgresIndicator when the user has reached the end of the list and new data will be loaded, or a UILabel when there are no more data to be fetched.
I have used the code below, but nothing happens:
UITableViewHeaderFooterView footer = new UITableViewHeaderFooterView ();
UILabel futerlabel = new UILabel ();
futerlabel.Text = "Duke u ngarkuar";
footer.AddSubview (futerlabel);
Any way how to achieve this.
If you are in a UITableViewController try this:
TableView.TableFooterView = footer;
UPDATE
After having a think about this I would suggest not using a footer but rather an extra cell at the end of your data, this will get this effect.
Using this method to check if you have scrolled to the last item and to update the table's data:
public override void WillDisplay (UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
{
// if showing last row of last section, load more
if (indexPath.Section == tableView.NumberOfSections()-1 && indexPath.Row == tableView.DataSource.RowsInSection(tableView, indexPath.Section)-1 && !FullyLoaded) {
var growRowSource = tableView.DataSource as GrowRowTableDataSource;
if (growRowSource != null) {
FullyLoaded = growRowSource.LoadNextPage ();
Task.Delay (5000);
tableView.ReloadData ();
}
}
}
And then in the Delegate checking for the last item and creating a different cell like so:
public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath)
{
if (indexPath.Row == LoadedItems.Count) {
var loadingCell = tableView.DequeueReusableCell (LoadingCellID, indexPath) as LoadFooterCell;
loadingCell.Loading = !hasNextPage;
return loadingCell;
}
var cell = tableView.DequeueReusableCell (CellID, indexPath) as GrowRowTableCell;
var item = LoadedItems [indexPath.Row];
// Setup
cell.Image = UIImage.FromFile(item.ImageName);
cell.Title = item.Title;
cell.Description = item.Description;
return cell;
}
bool hasNextPage;
I quickly mocked an example from the GrowTable Xamarin sample code here:
https://github.com/b099l3/LoadingTableExample
You could accomplish this in several ways, I will layout a few here:
In your TableViewSource you can do this:
1.) Implement: public override UIView GetViewForFooter(UITableView tableView, nint section) and return your UILabel
2.) Implement public override nfloat GetHeightForFooter(UITableView tableView, nint section) and return a height for your UIView
If your Footer is going to be a simple UILabel, you can replace Step 1 above with this:
Implement public override string TitleForFooter(UITableView tableView, nint section) and return "Duke u ngarkuar".
You will still need to implement public override nfloat GetHeightForFooter(UITableView tableView, nint section) and return a height otherwise your footer wont show up.
Alternatively, UITableView exposes a property called TableFooterViewthat allows you to set a UIView for a footer.
You can size this to your liking.
var footerView = new UIView(new RectangleF(0, 0, 375, 66));
TableView.TableFooterView = footerView;
I have been working on CustomCell in Xamarin.iOS platform. The following code is working fine. I have tableItems which is List that stores Start and End values.
And I also have a class(SettingCustomCell) where I have programmatically created TextFields to display Start and End values.
I wonder how could I detect/capture when user changes either Start or End values in the TextField in my current implementation.
MainTableViewController
tableItems.Add (new TableItem() {Start=1000, End=4000});
tableItems.Add (new TableItem() {Start=4000, End=6000});
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
SettingsCustomCell cell = tableView.DequeueReusableCell (cellIdentifier) as SettingsCustomCell;
if (cell == null) {
cell = new SettingsCustomCell (cellIdentifier);
}
cell.UpdateCell (tableItems [indexPath.Row].Start, tableItems [indexPath.Row].End);
return cell;
}
SettingsCustomCell
public CustomCell (NSString cellId) : base (UITableViewCellStyle.Default, cellId)
{
SelectionStyle = UITableViewCellSelectionStyle.None;
firstLabel = new UITextField ();
secondLabel = new UITextField ();
ContentView.Add (firstLabel);
ContentView.Add (secondLabel);
}
public void UpdateCell (int caption, int subtitle)
{
firstLabel.Text = caption.ToString();
secondLabel.Text = subtitle.ToString();
}
Create the eventhandler in the tablecell. And when the your UITextField text change call this eventhandler.
public EventHandler<bool> EditingChanged;
//some code here
firstTextField.ValueChanged += (s, e) => {
if(EditingChanged!=null)
EditingChanged(this,true);
}
Than in your DataSource you subscribe for EditingChanged event and create another eventhandler which will be called when the EditingChanged will be executed.
public EventHandler<bool> SourceEditingChanged;
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
SettingsCustomCell cell = tableView.DequeueReusableCell (cellIdentifier) as SettingsCustomCell;
if (cell == null) {
cell = new SettingsCustomCell (cellIdentifier);
}
cell.UpdateCell (tableItems [indexPath.Row].Start, tableItems [indexPath.Row].End);
cell.EditingChanged += {
if(SourceEditingChanged!=null)
SourceEditingChanged(this,true);
};
return cell;
}
Subscribe for your SourceEditingChange Event from viewController.
MySource.SourceEditingChange += (s,e) =>{
//Your Code here
}
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!