2013-09-13 3 views
0

У меня есть UIViewController, который содержит UIScrollView, который содержит как UITableView, так и еще UIScrollView. Внутри вложенного UIScrollView есть еще UITableView (есть способ этого безумия, голый со мной).Большое UITable останавливает приложение до остановки

Когда в ViewDidAppear из UIViewController рассчитать, насколько большой таблицы должны быть (намного больше, чем экран) и установить их размеры, а затем установить размер содержания UIScrollView, чтобы соответствовать таблицам, которые они содержат (UIScrollView обеспечит прокрутка, а не сама таблица). Все это отлично работает в симуляторе, но на самом устройстве он останавливается, привязывая процессор на 100% в течение десятков секунд. Это, очевидно, неприемлемо. Кто-нибудь знает, почему? Или как я могу обойти это?

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

OuterScrollView.ContentSize = new SizeF (View.Frame.Width, tableHeight); 
InnerScrollView.ContentSize = new SizeF (InnerTable.Frame.Width, tableHeight); 
InnerScrollView.Frame = new RectangleF(InnerScrollView.Frame.Location, 
         new SizeF(InnerScrollView.Frame.Width, tableHeight)); 

// So far so good 
OuterTable.Frame = new RectangleF(OuterTable.Frame.Location, 
      new SizeF(OuterTable.Frame.Width, tableHeight)); // this slows everything down!! 
InnerTable.Frame = new RectangleF(InnerTable.Frame.Location, 
        new SizeF(InnerTable.Frame.Width, tableHeight)); // and so does this 

Удаление обоих утверждений настройки таблицы .Frame и все работает достаточно быстро, но с ними это очень медленно. И медлительность не приходит прямо здесь, а где-то после звонка на базу ViewDidAppear.

Update: У меня было прозрение и подумал , если изменение размера таблицы является проблемой, просто сделать таблицы достаточно большим, что они не нуждаются в изменении размеров. В настройках, которые у меня есть, прокрутка обрабатывается просмотром прокрутки, а не самой таблицей, поэтому я мог бы просто установить таблицу как действительно большой и позволить прокруткам ContentSize позаботиться об обрезке пустой части таблицы. Это работает в том смысле, что он показывает, как я хочу, но это на самом деле еще медленнее! Поэтому я пришел к выводу, что проблема не в изменении размера таблицы, а в присутствии очень долгого (в этом случае я установил высоту 4000, а размер изменил ее на 2,354).

Фон: Чтобы добавить немного больше к тому, что я пытаюсь сделать. Поскольку Apple в своей мудрости решила, что никто не нуждается в сетке, такой как контроль, я пытаюсь настроить ситуацию, когда у меня есть вид в виде сетки, где левые столбцы остаются на месте, но вы можете горизонтально прокручивать правую часть экрана, большинство столбцов, и при прокрутке по вертикали все будет оставаться в синхронизации. После некоторого поиска я наткнулся на решение (извините, не могу вспомнить, где именно), что с небольшими настройками (в симуляторе). В принципе, вы вставляете таблицы в виде прокрутки, чтобы вид прокрутки мог обрабатывать прокрутку. Раскладка выглядит примерно так:

+-------------------------Outer Scroll-------------------------+ 
|     +---------------Inner Scroll---------------+| 
|+--Fixed Table--+ |+---------Scrolling Table----------------+|| 
||    | ||          ||| 
||    | ||          ||| 
||    | ||          ||| 
||    | ||          ||| 
||    | ||          ||| 
||    | ||          ||| 
|+---------------+ |+----------------------------------------+|| 
|     +------------------------------------------+| 
+--------------------------------------------------------------+ 

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

Другое обновление: Таким образом, проблема заключается в том, что таблица не повторно использует ячейки при ее установке. Я предполагаю, что логика повторного использования ячеек распространяется только на определение того, находится ли ячейка внутри фрейма таблицы, а не какая-то часть таблицы. Таким образом, с 50 элементами вместо отображения 6-7, а затем повторного использования этих ячеек, он создает все 50 независимо.Поэтому я отказался от моей ранее попытки и попытался синхронизировать скроллинг между двумя таблицами, как это:

OuterTable.Scrolled += (sender, arg) => 
     { 
      InnerTable.ContentOffset = new PointF(InnerTable.ContentOffset.X, 
       OuterTable.ContentOffset.Y); 
     }; 

InnerTable.Scrolled += (sender, arg) => 
     { 
      OuterTable.ContentOffset = new PointF(0, InnerTable.ContentOffset.Y); 
     }; 

Это почти работает, за исключение IOS не любит горизонтальную прокрутку для таблиц, так что внутренняя таблица все еще должна быть обернута вид прокрутки (устанавливается с помощью ContentSize, чтобы покрыть ширину, которую мне нужно прокрутить). На данный момент это почти работ. Обычно это будет происходить без сглаживания, но с небольшим количеством беспорядков вы можете получить, например, внутреннюю таблицу для прокрутки по диагонали (несмотря на то, что установка блокировки на всех), и в некоторых случаях можно получить их вне синхронизации , который выглядит действительно глупо. Таким образом, это не совсем так же визуально, но, по крайней мере, оно не повредит поток пользовательского интерфейса так же плохо.

+0

любой шанс, что они перекрываются одним пикселем? Попробуйте помещать пространство между ними. Но в основном это звучит как сумасшедший дизайн пользовательского интерфейса (и обратите внимание на документацию, говорящую о том, чтобы не встраивать объекты UITableView в объекты UIScrollView). – Dad

+0

@Dad: На самом деле выяснилось, что когда я определял высоту представления прокрутки на 'ViewDidLoad', но он был изменен iOS (чтобы принять во внимание панель вкладок внизу) к тому времени, когда он попал в' ViewDidAppear ', поэтому он думал, что он должен быть вертикально прокручиваемым, когда это должно быть. Я просто переместил размер прокрутки в «ViewDidAppear», и теперь он отлично работает, и у меня больше нет проблемы с синхронизацией. –

+0

спасибо за обновление. – Dad

ответ

1

Вы пытались сделать это с автозапуском? Там вы не несете ответственность за то, что представления действительно изменяются, просто установите ограничения в viewDidLoad и дайте остальным позаботиться о системе.

Но в терминах ручной раскладки - я не понимаю, почему это на самом деле произошло. Когда вы профилировали его с помощью инструментов, какова была медленная часть Time Profiler?

+0

Я не уверен, что здесь будет работать автозапуск.Стол должен быть длиннее окна, в котором он отображается, но он является динамическим, он должен быть рассчитан во время выполнения. Высота таблицы в основном рассчитывается как количество строк, умноженное на высоту строки, так что сама таблица не будет прокручиваться. –

+0

Что касается инструментов, не смотря на то, что после того, как он подтянул это представление, процессор привязывается на уровне около 100%, но я не получаю от него больше (но отчасти это может быть моя неопытность с его использованием). Исходя из Xamarin, в инструменты, я думаю, что много потенциально полезной информации теряется. –

+0

Попробуйте профилировщик времени. Вы должны увидеть, где процессор проводит все свое время. – czechboy

1

Из документации:

Важно: Вы не должны вставлять UIWebView или UITableView объекты в объектов UIScrollView. Если вы это сделаете, неожиданное поведение может привести к , потому что события касания для двух объектов могут быть перемешаны и ошибочно обработаны .

Возможно, ваш интерфейс может быть медленным, потому что события касания обрабатываются неправильными объектами. Это может привести к тому, что вид прокрутки будет скакать, действовать лагги или вообще не реагировать.

Опишите поведение, в котором вы собираетесь судить? Можете ли вы достичь того, что хотите, используя только UITableView с UIScrollView в нем или, возможно, UICollectionView?

+0

Прокрутка не проблема. Пользовательский интерфейс полностью заблокирован около 30 секунд. После этого он прокручивается просто отлично, поэтому я не думаю, что проблема связана с взаимодействием таблицы и прокрутки (FWIW: прокрутка отключена в таблицах) –

+0

Интересно. Запускает ли Xamarin Studio паузу во время выполнения и проверяет потоки? Что произойдет, если вы приостановите Xcode во время зависания и проверите операцию в основном потоке? –

+0

Да, инструменты Xamarin невелики. Вы можете взять снимки памяти и посмотреть на кучу, но профилирование, в котором код тратит время, кажется сложнее. Тем не менее, я думаю, проблема может заключаться в том, что с большой таблицей iOS хочет создать все ячейки с места в карьер вместо создания (или, скорее, повторного использования), когда они фактически прокручиваются в представлении. –

1

Похоже, что единственный способ для вашей предлагаемой реализации состоит в том, чтобы загрузить ВСЕ пользовательский интерфейс при инициализации, что устраняет преимущества производительности при использовании UITableView вообще. Это будет значительно более эффективно (с точки зрения памяти) для того, чтобы у вас был UITableView верхнего уровня, который прокручивается нормально и содержит прокрутку UIScrollview по горизонтали в каждой ячейке.

+-------------------------Table View---------------------------+ 
|+-----------------------Table View Cell---------------------+| 
||+--Fixed Section--+ +---------Synched Scroll View---------+|| 
|||     | |          ||| 
|||     | |          ||| 
||+-----------------+ +-------------------------------------+|| 
|+-----------------------------------------------------------+| 
|+-----------------------Table View Cell---------------------+| 
||+--Fixed Section--+ +---------Synched Scroll View---------+|| 
|||     | |          ||| 
|||     | |          ||| 
||+-----------------+ +-------------------------------------+|| 
|+-----------------------------------------------------------+| 
|+-----------------------Table View Cell---------------------+| 
||+--Fixed Section--+ +---------Synched Scroll View---------+|| 
|||     | |          ||| 
|||     | |          ||| 
||+-----------------+ +-------------------------------------+|| 
|+-----------------------------------------------------------+| 
+--------------------------------------------------------------+ 

Важный шаг является синхронизация горизонтальных взглядов прокрутки, которые вы можете сделать, отправив NSNotifications или пользовательские сообщения делегата на -scrollViewDidScroll:

Это может чувствовать расточительно создавать 10+ scrollviews внутри таблицы но на практике он становится довольно эффективным.

+0

Это интересное предложение и, в конечном счете, может быть легче работать, чем в беспорядке, в котором я оказался. Тем не менее, то, что у меня есть, работает, и у меня нет времени прямо сейчас, чтобы вернуться и попробовать, чтобы увидеть, лучше ли это или хуже того, что у меня есть. В следующий раз я обязательно попробую это. –

Смежные вопросы