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

Не знаю с чем это связано, но мне это не понравилось, поэтому было решено потратить некоторое время на решение данной проблемы, прошу под кат.
Начнем. У нас имеется обычный такой UITableView со свойством
tableView.Editing = true;
Так же, в UITableViewSource у нас есть переопределенный метод
public override bool CanMoveRow (UITableView tableView, NSIndexPath indexPath) => true;
Если запустим приложение — увидим, что с этим свойством мы можем перемещать ячейки таблицы в пределах фрейма самой таблицы.
public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath) =>UITableViewCellEditingStyle.None;
Теперь зададимся вопросом о том, как сделать так, чтобы строки перемещались не только по тапу на ту маленькую область, отведённую обделённому пользователю, а по всей ячейке.
Решение проблемы выглядит так:
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 и выше.
До:

После:

При переносе ячейка становится прозрачной, поэтому, если вы хотите подкрасить ее или как-то стилизовать — делайте это с помощью cell.BackgroundView.
На мой взгляд, код выглядит достаточно простым и понятным. Скорее всего, для матёрых разработчиков Америки я не открыл, но новичкам будет это полезно знать, да и статей про разработку на Xamarin не так уж и много. Так что, если тема будет актуальна, могу пилить дальше интересные фокусы с интерфейсами Xamarin.IOS/Android и не только.
На этом всё, по возможности буду отвечать в комментариях.
ссылка на оригинал статьи http://habrahabr.ru/post/265171/
Добавить комментарий