Обновление размера содержимого родительского UIScrollView после drawRect в subview

#iphone #objective-c #cocoa-touch #ipad #uiview

#iPhone #objective-c #cocoa-touch #iPad #uiview

Вопрос:

У меня есть UIScrollView с UIView в нем.

Я не знаю размер подвида, пока в нем не будет отображено все, что необходимо, и это может измениться на последующих чертежах. (В нем есть таблицы, текст и т.д., Которые Добавляются постепенно). Итак, мне нужно обновить размер содержимого в режиме прокрутки в момент завершения drawRect в subview.

Есть ли хороший способ запустить требуемые [myScrollView setContentSize] и [mySubView setNeedsDisplay] (это вызывает drawRect, поэтому я приму меры, чтобы избежать бесконечных циклов) после drawRect или любое другое решение, которое действительно работает в этой ситуации?

Похоже, требуется setNeedsDisplay, вызываемый в подпросмотре, до того, как будет произведено изменение размера содержимого. Все, что мне нужно сделать, это установить setContentSize из drawRect в вложенном представлении, затем я нажимаю кнопку, которая запускает setNeedsDisplay, после чего размер содержимого обновляется нормально. Итак, я мог бы просто установить таймер и дождаться следующего цикла запуска, чтобы выполнить setNeedsDisplay? Но это ужасный взлом. Также я предполагаю, что изменение размера содержимого в коде, вызываемом из drawRect подвида, недопустимо, если UIKit полагается на то, что иерархия представлений остается постоянной, пока она находится в середине рисования иерархии представлений.

Ответ №1:

Вы могли бы использовать NSNotification.

В конце вашего кода рисования отправьте уведомление.

         [[NSNotificationCenter defaultCenter] 
                      postNotificationName:@"drawingLoopDone_Notification"
                                    object:nil];
  

Добавьте соответствующий контроллер представления в качестве NSObserver уведомления.

   [[NSNotificationCenter defaultCenter] 
          addObserver:self 
             selector:@selector(setNeedsDisplay)
                 name:@"drawingLoopDone_Notification" 
               object:nil];
  

После получения уведомления (или в вашем viewDidUnload) очистите прослушиватель уведомлений следующим образом:

     [[NSNotificationCenter defaultCenter] 
                removeObserver:self name:@"drawingLoopDone_Notification" object:nil];
  

Комментарии:

1. 1 за попытку, но это не сработало. Метод вызывается сразу, так что это так же, как если бы я вызвал его напрямую. drawRect отправляет уведомление, вызывается селектор, затем выполнение возвращается к drawRect, поэтому, когда оно заканчивается, флаг setNeedsDisplay сбрасывается системой.

2. Что ж, это разочаровывает. Время использовать большие пушки. Я думаю, вам нужно создать 2 экземпляра NSInvocationOperation — drawRect и setContentSize, причем setContentSize зависит от drawRect — и поместить их в NSOperationQueue. Я не знаю, требует ли ваша ситуация соблюдения значения ключа или нет. Я выполнил только относительно простые реализации операционных очередей, поэтому все, что я могу честно сделать, это указать вам на эти документы и пожелать вам удачи.

3. Не будет ли это страдать от той же проблемы? Это также похоже на серьезную переработку.

Ответ №2:

Я только что использовал…

 [theView performSelector:@selector(someSelector) withObject:nil afterDelay:0.0];
  

… что, по крайней мере, заставляет хак работать, потому что он не вызывает селектор до завершения drawRect, поэтому setNeedsDisplay (ведущий к другому drawRect с проверкой, чтобы избежать зацикливания), который, по-видимому, необходим, не отменяется.

Я все еще хотел бы услышать, есть ли более стандартный способ обновить размер содержимого в режиме прокрутки, когда вы не знаете размер этого subview, пока он не был нарисован.

Комментарии:

1. Не могли бы вы поделиться своим окончательным решением в деталях?