Фреймы ячеек UITableView с измененным размером не обновляются

#ios #uitableview #xamarin.ios

#iOS #uitableview #xamarin.ios

Вопрос:

У меня есть UITableView, размер которого я изменяю, когда отображается клавиатура.

 // MonoTouch code

// Resize the table so it's not hidden by the keyboard
var keyboardFrame = UIKeyboard.BoundsFromNotification(notification);
var tableFrame = myTable.Frame;
tableFrame.Height = theView.Frame.Height - keyboardFrame.Height;
myTable.Frame = tableFrame;

// Bring the current cell back in view
this.InvokeOnMainThread(()=>{
    if(currentCell != null) myTable.ScrollRectToVisible(currentCell.Cell.Frame, true);
});
  

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

Я попробовал следующее, все они дали те же результаты, что и фрейм, все еще указывающий на старое местоположение (многие из них экспериментировали, чтобы увидеть, сделали ли они что-нибудь, не зная, что сработает, а что нет):

  • Используя setNeedsLayout для ячейки, вложенных представлений таблицы, таблицы.
  • Использование layoutIfNeeded для ячейки, вложенных представлений таблицы, самой таблицы и представления, содержащего таблицу
  • Требуется несколько комбинаций setNeedsLayout и layoutIfNeeded
  • Запускаю новый поток, сплю в этом потоке смехотворное количество времени (чтобы дать время пользовательскому интерфейсу выполнить перерисовку / обновление / что угодно), а затем просматриваю фрейм
  • Запуск нового потока, переход в спящий режим в течение этого смехотворного количества времени, а затем вызов различных функций макета

Я не уверен, происходит ли сбой из-за изменения размера или прокрутки.

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

Кто-нибудь знает, как заставить UITableView обновлять фреймы своих ячеек, не выполняя reloadData (reloadData вызывает много нежелательных эффектов в этом случае)?

Ответ №1:

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

Изменение фрейма или границ UITableView или любого другого представления, если на то пошло, не обязательно изменяет фрейм (ы) его подвидов. Это поведение зависит от свойства contentMode супервизора.

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

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