#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. Не могли бы вы поделиться своим окончательным решением в деталях?