2009-10-07 5 views
3

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

Я не думаю, что для достижения этой цели я могу использовать обычное масштабируемое поведение 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 
    } 
} 

Я думал, что переопределение touchesBegan: withEvent :, touchesMoved: withEvent :, touchesEnded: withEvent: и touchsCancelled: withEvent: таким образом должен работать, но это не так.

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

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

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

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

ответ

3

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

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

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

+0

ОК, спасибо, я попробую перехватить setTransform и перерисовать вид в конце масштабирования. Я могу попытаться полностью перерисовать мой взгляд и посмотреть, как выглядит производительность. Сегодня я не смогу сделать это, но я дам вам знать, как я пойду. –

+0

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

0

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

Я думал, что переопределение touchesBegan: withEvent :, touchesMoved: withEvent :, touchesEnded: withEvent : и touchsCancelled: withEvent: в этом путь должен работать, но это не так.

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

if ([touches count] != 2) 

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

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

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

+0

я основывал это на главе в Начиная iPhone 3 Программирование, где касания NSSet используются для доступа к касаниям. Я не знал, что этот NSSet может не содержать все касания при каждом касанииMoved: withEvent: вызывается. –

+0

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

0

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

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

Также в коде у вас есть, у вас есть touchesBegan: withEvent: но тогда вы направляете супер touchesMoved: withEvent: вместо touchesBegan: withEvent:

+0

Я пробовал перерисовывать мой контент каждый раз, и, хотя он отлично работает в симуляторе, он даже не удалённо приемлем на моем iPhone 3G. С данными, которые я тестировал, я рисовал всего 9 CGPaths. В настоящее время мой UIScrollView прозрачен, что, вероятно, влияет на производительность. В любом случае, вы должны попробовать проверить свой код на самом устройстве - я не удивлюсь, если перерисовка во время масштабирования будет слишком медленной в вашем случае. –

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