Swipe to delete cell Height is decrease every time in xamarin ios - ios

I am new to iOS. I am creating TableView with swipe to delete the cell. But When I swipe every time the cell height is decrease. I am using iOS 10. The below code I have used.
Code :
class AppointmentSourceClass : UITableViewSource
{
List<AppointmentItem> appointments;
public AppointmentSourceClass(List<AppointmentItem> appointments)
{
this.appointments = appointments;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
ApointListCell cell = tableView.DequeueReusableCell(ApointListCell.Key) as ApointListCell ?? ApointListCell.Create();
var item = appointments[indexPath.Row];
cell.BindData(item);
cell.Layer.MasksToBounds = false;
cell.Layer.CornerRadius = 5.0f;
cell.BackgroundColor = UIColor.White;
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
return cell;
}
public override void CommitEditingStyle(UITableView tableView, UITableViewCellEditingStyle editingStyle, NSIndexPath indexPath)
{
switch (editingStyle)
{
case UITableViewCellEditingStyle.Delete:
appointments.RemoveAt(indexPath.Row);
tableView.DeleteRows(new NSIndexPath[] { indexPath},UITableViewRowAnimation.Fade);
break;
case UITableViewCellEditingStyle.None:
break;
}
}
public override bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
{
return true;
}
public override string TitleForDeleteConfirmation(UITableView tableView, NSIndexPath indexPath)
{
return "Trash ( ";
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return appointments.Count;
}
}
}
Output :
Before Swipe Image :
After Swipe Image :

Found the solution.
In the TableCell I have use below code to seperate the two tableCell and make space between them. If i remove the code then it working fine.
public override CoreGraphics.CGRect Frame
{
get
{
return base.Frame;
}
set
{
value.Y += 4;
value.Height -= 2 * 4;
base.Frame = value;
}
}

Related

How to read cell value long press gesture on table cell in xamarin.ios?

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.

Cell size not changed in collection view IOS (Implemented in Xamarin)

I have a collection view that needs to have the cells fitting size to content.
I use sizeForItemAtIndexPath: to set size for each cell.
It's fired and works great.
Here is the problem what I am facing.
The data list for collection view is changed dynamically.
collection view has only 1 item to show and shows it in correct cell size(let's say size1)
next time collection view has 1 item to show again but it's different data.
In this case, the collection view doesn't show it in correct cell size. it shows in size1
I want to show next item in its own size but collection view keep original size.
When item count is changed, sizeForItemAtIndexPath: is fired again.
When item count is same, it's not fired.
I want it to be fired everytime.
I share some of my code.
cllSelected.Source = new SelectedItemSource(this, _selectedItems);
Above code will be called whenever there is new _selectedItems
I implemented the UICollectionViewSource as following
public class SelectedItemSource : UICollectionViewSource, IUICollectionViewDelegateFlowLayout
{
CatalogVC _ownerVC;
SelectedCategoryList _selectedItems;
public SelectedItemSource(CatalogVC ownerVC, SelectedCategoryList selectedItems)
{
_ownerVC = ownerVC;
_selectedItems = selectedItems;
}
public override nint NumberOfSections(UICollectionView collectionView)
{
return 1;
}
public override nint GetItemsCount(UICollectionView collectionView, nint section)
{
return _selectedItems != null ? _selectedItems.Count : 0;
}
public override bool ShouldHighlightItem(UICollectionView collectionView, Foundation.NSIndexPath indexPath)
{
return true;
}
public override void ItemHighlighted(UICollectionView collectionView, Foundation.NSIndexPath indexPath)
{
}
public override void ItemUnhighlighted(UICollectionView collectionView, Foundation.NSIndexPath indexPath)
{
_ownerVC.SelectedFilter_ItemClick(indexPath.Row);
}
public override UICollectionViewCell GetCell(UICollectionView collectionView, Foundation.NSIndexPath indexPath)
{
SelectedFilterCollectionCell cell = collectionView.DequeueReusableCell("SelectedFilterCollectionCell", indexPath) as SelectedFilterCollectionCell;
cell.Layer.ShouldRasterize = true;
cell.Layer.RasterizationScale = UIScreen.MainScreen.Scale;
cell.BindDataToCell(_selectedItems[indexPath.Row]);
return cell;
}
[Export("collectionView:layout:sizeForItemAtIndexPath:")]
public CoreGraphics.CGSize GetSizeForItem(UICollectionView collectionView, UICollectionViewLayout layout, Foundation.NSIndexPath indexPath)
{
var text = new NSString(_selectedItems[indexPath.Row].Text);
CGSize cellSize = new CGSize(xxx, yyy); // cellSize will be determined according to text
return cellSize;
}
}
Thanks for any solution or suggestion!
Try to call CollectionView.ReloadData() after the data changes.
I think it will invoke the methods included in the delegate.

Single selection for every UITableViewSection iOS Xamarin

I have a UITableView with 2-3 sections. I want to implement a functionality where single row from every section can be selected.
Something like so :-
I have tried enabling multiple selection on the UITableView. But it allows me to select multiple rows from all the sections. I want to select only one row at a time from every section.
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.CellAt(indexPath);
if (cell.Accessory == UITableViewCellAccessory.None)
{
cell.Accessory = UITableViewCellAccessory.Checkmark;
}
else
{
cell.Accessory = UITableViewCellAccessory.None;
}
selectedSection = indexPath.Section;
}
public override void RowDeselected(UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.CellAt(indexPath);
cell.Accessory = UITableViewCellAccessory.None;
}
You can use a list to store flags for every section which you selected last time.
List<NSIndexPath> selectList = new List<NSIndexPath>();
for(int i = 0; i < tableviewDatasource.Count; i++)
{
//initial index 0 for every section
selectList.Add(NSIndexPath.FromRowSection(0, i));
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
//anti-highlight last cell
NSIndexPath lastindex = selectList[indexPath.Section];
var lastcell = tableView.CellAt(lastindex);
lastcell.Accessory = UITableViewCellAccessory.None;
//highlight selected cell
var cell = tableView.CellAt(indexPath);
cell.Accessory = UITableViewCellAccessory.Checkmark;
//update the selected index
selectList.RemoveAt(indexPath.Section);
selectList.Insert(indexPath.Section, indexPath);
}

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)
}

TextField Change event in a CustomCell

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
}

Resources