Как ограничить UIScrollView только масштабировать по вертикали? - PullRequest
4 голосов
/ 28 октября 2011

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

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

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

Я использую MonoTouch, но ответы с помощью Objective-C в порядке.

Ответы [ 4 ]

2 голосов
/ 11 июля 2013

Я знаю, что этот вопрос был опубликован довольно давно, но вот ответ для любого, кто застрял в этой проблеме.

Я просмотрел вопрос, с которым вы связались, rankAmateur, и я думаю, что простой способ исправить найденное там решение в соответствии с вашими потребностями состоит в замене свойства "a" в CGAffineTransform его свойством "d" в setTransform: метод .

- (void)setTransform:(CGAffineTransform)newValue;
{
 CGAffineTransform constrainedTransform = CGAffineTransformIdentity;
 // constrainedTransform.a = newValue.a;
 constrainedTransform.d = newValue.d;
 [super setTransform:constrainedTransform];
}

Я не очень хорошо разбираюсь в CGAffineTransorm, но это сработало для меня, и после просмотра документации кажется, что свойство "a" соответствует оси x представления, а свойство "d" соответствует оси y представления .

EDIT

Итак, вернувшись назад и поняв, что на самом деле был вопрос, я немного углубился в это, и я немного озадачен, но, испытав то же поведение, которое упоминает rankAmateur выше, для CGAffineTransform кажется невероятно необычным работать очень хорошо с zoomScale, когда масштабирование ограничено только по горизонтали, но не когда только вертикально.

Единственная гипотеза, которую я могу предложить, заключается в том, что она может иметь какое-то отношение к различным системам координат по умолчанию Core Graphics и UIKit, поскольку в этих системах координат ось X функционирует одинаково, а ось Y функционирует противоположно. Возможно, это каким-то образом запуталось в ранее упомянутом переопределении setTransform.

0 голосов
/ 02 сентября 2015

Этот ответ сильно зависит от ответа от starryVere (палец вверх!)

это код starryVere в Swift. Он находится в увеличенном подклассе UIView:

var initialScale: CGFloat = 1.0
override var transform: CGAffineTransform {
    set{
        //print("1 transform... \(newValue), frame=\(self.frame), bounds=\(self.bounds)")
        var constrainedTransform = CGAffineTransformIdentity
        constrainedTransform.d = self.initialScale * newValue.d // vertical zoom
        //constrainedTransform.a = newValue.a // horizontal zoom
        super.transform = constrainedTransform
        //print("2 transform... \(constrainedTransform), frame=\(self.frame), bounds=\(self.bounds)")
    }
    get{
        return super.transform
    }
}

Закомментированные отпечатки очень помогают понять, что происходит с границами и рамкой во время преобразования.

Теперь к проблеме масштаба:

метод scrollViewDidEndZooming содержащего UIScrollViewDelegate имеет шкалу параметров. Согласно моим тестам, этот масштабный параметр содержит значение zoomedView.transform.a, которое является горизонтальным масштабным коэффициентом, который мы установили на 1,0 с помощью CGAffineTransformIdentity. Так что масштаб всегда 1,0.

Исправить несложно:

func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) {
    let myScale = zoomView.transform.d

}

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

0 голосов
/ 19 ноября 2014

После борьбы с той же проблемой, я смог найти обходной путь. Используйте этот код для метода setTransform.

-(void)setTransform:(CGAffineTransform)transform
{
    CGAffineTransform constrainedTransform = CGAffineTransformIdentity;
    constrainedTransform.d = self.initialScale * transform.d;
    constrainedTransform.d = (constrainedTransform.d < MINIMUM_ZOOM_SCALE) ? MINIMUM_ZOOM_SCALE : constrainedTransform.d;
    
    [super setTransform:constrainedTransform];
}
                                                                          

Установите свойство initialScale из метода делегата scrollViewWillBeginZooming.

0 голосов
/ 28 октября 2011

Будет более полезно, если вы предоставите пример кода того, что вы пытаетесь, но я дам вам несколько строк, чтобы попробовать.На самом деле вы должны сделать ширину содержимого размером равным «320», то есть равным размеру экрана iPhone.

scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 45,320,480)];   
scrollView.contentSize = CGSizeMake(320,1000);
scrollView.showsVerticalScrollIndicator = YES;

Версия MonoTouch выглядит следующим образом:

scrollView = new UIScrollView (new RectangleF (0, 45, 320, 480)) {
    ContentSize = new SizeF (320, 1000),
    ShowVerticalScrollIndicator = true
};

Надеюсь, это поможет.. :) и да, не забудьте принять ответ, если он поможет: D

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