Кастомизация ручной сортировки UITableView на Xamarin

от автора

В данной статье будет рассмотрен способ модификации UITableView для переноса ячеек таблицы. Вспомним, что Apple нам предлагает тягать ячейки за строго отведенное место:

image

Не знаю с чем это связано, но мне это не понравилось, поэтому было решено потратить некоторое время на решение данной проблемы, прошу под кат.

Начнем. У нас имеется обычный такой UITableView со свойством

tableView.Editing = true; 

Так же, в UITableViewSource у нас есть переопределенный метод

public override bool CanMoveRow (UITableView tableView, NSIndexPath indexPath) => true; 

Если запустим приложение — увидим, что с этим свойством мы можем перемещать ячейки таблицы в пределах фрейма самой таблицы.

Спойлер

Кстати, контрол редактирования слева убирается так:

public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath) =>UITableViewCellEditingStyle.None; 

Теперь зададимся вопросом о том, как сделать так, чтобы строки перемещались не только по тапу на ту маленькую область, отведённую обделённому пользователю, а по всей ячейке.

inb4

Нельзя просто изменить фрейм этого самого контрола, он работает немного иначе, чем можно себе представить, если заинтересует кого-то — расскажу в следующем посте.

Решение проблемы выглядит так:

foreach (var item in cell.Subviews) { 					if (item.Description.Contains ("UITableViewCellReorderControl")) {  						UIView resizedGripView = new UIView(new CGRect(0,0,item.Frame.GetMaxX(),item.Frame.GetMaxY())); 						resizedGripView.AddSubview(item); 						cell.AddSubview(resizedGripView);  			CGSize sizeDifference = new CGSize(resizedGripView.Frame.Size.Width - item.Frame.Size.Width, 							resizedGripView.Frame.Size.Height - item.Frame.Size.Height);  			CGSize transformRatio = new CGSize(resizedGripView.Frame.Size.Width / item.Frame.Size.Width, 							item.Frame.Size.Height / item.Frame.Size.Height);  						CGAffineTransform transform = CGAffineTransform.MakeIdentity();  			transform = CGAffineTransform.Scale(transform, transformRatio.Width, transformRatio.Height); 						nfloat two = new nfloat (2.0); 						nfloat df = -sizeDifference.Width / two; 						nfloat dff = -sizeDifference.Height / two; 						transform = CGAffineTransform.Translate(transform, df,dff);  						resizedGripView.Transform = transform; 						item.Subviews [0].RemoveFromSuperview (); 					} 				} 

Далее стояла задача задать стиль ячейки при её переносе. Здесь появился вопрос с тенью, отбрасываемой переносимой ячейкой, эта тень никак не хотела пропадать. После долгих попыток поиска той самой заветной сабвью, всё-таки удалось её отыскать где-то в недрах таблицы, под монотонное стучание бубна.

Делается это в переопределённых методах самой UITableView

UIView wrapperview;  public override UIView[] Subviews { 			get { 				foreach (var item in base.Subviews) {  					if (item.Description.Contains("UITableViewWrapperView")) { 						wrapperview = item; 					} 					if (item.Description.Contains("UIShadowView")) { 						item.Hidden = true; 					} 				}  				return base.Subviews; 			} 		}  		public override void LayoutSubviews () 		{ 			base.LayoutSubviews (); 			foreach (var item in wrapperview.Subviews) { 				if (item.Description.Contains("UIShadowView")) { 					item.Hidden = true; 					item.Layer.ShadowColor = UIColor.White.CGColor; 				} 			} 		} 

Этот код подойдет для любой версии IOS, от 6 и выше.

До:
image

После:
image

При переносе ячейка становится прозрачной, поэтому, если вы хотите подкрасить ее или как-то стилизовать — делайте это с помощью cell.BackgroundView.

На мой взгляд, код выглядит достаточно простым и понятным. Скорее всего, для матёрых разработчиков Америки я не открыл, но новичкам будет это полезно знать, да и статей про разработку на Xamarin не так уж и много. Так что, если тема будет актуальна, могу пилить дальше интересные фокусы с интерфейсами Xamarin.IOS/Android и не только.

На этом всё, по возможности буду отвечать в комментариях.

ссылка на оригинал статьи http://habrahabr.ru/post/265171/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *