Реализуйте пользовательское масштабирование для UIScrollView - PullRequest
3 голосов
/ 07 октября 2009

У меня есть UIScrollView с требованием, чтобы при масштабировании contentSize.height оставался неизменным. Увеличение от 200x100, например, должно привести к новому контенту размером 400x100 вместо 400x200, например. Я хотел бы сделать свой собственный рисунок, пока пользователь масштабирует.

Я не думаю, что смогу использовать нормальное масштабирование UIScrollView для достижения этой цели, поэтому я пытаюсь свернуть свое собственное. (Я мог бы просто позволить ему сделать свое дело, а затем перерисовать мое содержимое, когда вызывается -scrollViewDidEndZooming: withView: atScale: но это не очень красиво).

В настоящее время я создаю подкласс UIScrollView и пытаюсь выполнить собственное масштабирование, когда на экране два пальца:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([touches count] != 2) {
        [super touchesMoved:touches withEvent:event];
    } else {
     // do my own stuff
    }
}

Я думал, что путем переопределения прикосновений Beg: withEvent :, touchesMoved: withEvent :, touchesEnded: withEvent: и touchesCancelled: withEvent: таким образом должно работать, но это не так.

Ранее неудачная попытка состояла в том, чтобы поместить прозрачный вид поверх вида прокрутки и отправить штриховые штрихи, которые мне не интересны, в вид прокрутки:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([touches count] != 2) {
        [self.theScrollView touchesMoved:touches withEvent:event];
    } else {
     // do my own stuff
    }
}

Любая помощь будет оценена.

Спасибо, Томас

Ответы [ 3 ]

3 голосов
/ 07 октября 2009

Вероятно, вы не сможете поддерживать приличную производительность во время масштабирования, если попытаетесь перерисовать ваш контент в каждом кадре события масштабирования. Я бы рекомендовал использовать подход, позволяющий UIScrollView увеличивать или уменьшать масштабированную версию вашего чертежа, а затем перерисовывать содержимое, чтобы оно было четким в конце масштабирования в -scrollViewDidEndZooming: withView: atScale: делегат метод. Это то, что я делаю в своем приложении, и в итоге оно работает очень хорошо.

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

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

0 голосов
/ 08 октября 2009

Я пытаюсь сделать то же самое, что и это, и я действительно хочу иметь возможность перерисовывать, пока он масштабируется. Исправление в конце в scrollViewDidEndZooming: withView: atScale недостаточно хорош.

Способ, которым я это делаю, - это передать фиктивное представление в viewForZoomingInScrollView: и прочитать высоту этого фиктивного представления и установить кадр в реальном представлении содержимого на то, что я хочу. Поскольку кадр изменяется, это означает, что drawRect вызывается каждый раз. На симуляторе все нормально, я просто рисую несколько линий. Но на самом деле я не являюсь владельцем устройства, поэтому не могу его правильно протестировать.

Также в коде, который вы получили, у вас есть штрихи Beg: withEvent: но затем вы переадресовываетесь на супер касания Moved: withEvent: вместо прикосновений

0 голосов
/ 07 октября 2009

Я не уверен, что вы подразумеваете под этим:

Я думал, что переопределив touchesBegan: withEvent :, touchesMoved: withEvent :, прикосновения закругленные: с событием: и TouchCancelled: withEvent: в этом путь должен работать, но это не так.

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

if ([touches count] != 2)

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

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

Если вы не получаете сенсорные события, то это совсем другая проблема, вам может понадобиться включить set multiTouchEnabled:YES

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...