Как установить минимальный и максимальный масштаб масштабирования с помощью UIPinchGestureRecognizer

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

[recognizer view].transform = CGAffineTransformScale([[recognizer view] transform], [recognizer scale], [recognizer scale]);
recognizer.scale = 1;

это работает нормально для увеличения и уменьшения. Но проблема в том, что я хочу увеличивать и уменьшать масштаб в определенном масштабе, как в UIScrollView, мы можем установить maxZoom и minZoom. я не мог найти никакого решения для этого, каждый учебник о UIPinchGestureRecognizer просто описывает один и тот же код.

 TheTiger09 июн. 2012 г., 08:53
@nhahtdh - Большое спасибо за ваш ответ .. но я пока не могу найти какое-либо решение :-(
 nhahtdh09 июн. 2012 г., 07:49
Вам придется написать свой собственный код. Я сделал то же самое в одном из своих заданий, но я не помню, насколько хорошо это работает:github.com/nhahtdh/PS5/blob/master/Game/GameObject.mm#L295 Я советую вам пройтись по нему еще раз и уточнить его в соответствии с вашими требованиями.

Ответы на вопрос(4)

Решение Вопроса

CGFloat __scale а такжеCGFloat __previousScale в интерфейсе класса, который обрабатывает жест. Задавать__scale в1.0 переопределив один изinit функции (не забудьте вызвать супер конструктор здесь).

-(void) zoom:(UIPinchGestureRecognizer *)gesture {

    NSLog(@"Scale: %f", [gesture scale]);
    if ([gesture state] == UIGestureRecognizerStateBegan) {
        __previousScale = __scale;
    }

    CGFloat currentScale = MAX(MIN([gesture scale] * __scale, MAX_SCALE), MIN_SCALE);  
    CGFloat scaleStep = currentScale / __previousScale;
    [self.view setTransform: CGAffineTransformScale(self.view.transform, scaleStep, scaleStep)];

    __previousScale = currentScale;

    if ([gesture state] == UIGestureRecognizerStateEnded || 
        [gesture state] == UIGestureRecognizerStateCancelled ||
        [gesture state] == UIGestureRecognizerStateFailed) {
        // Gesture can fail (or cancelled?) when the notification and the object is dragged simultaneously
        __scale = currentScale;
        NSLog(@"Final scale: %f", __scale);
    }
}
 TheTiger09 июн. 2012 г., 10:22
Большое спасибо, сэр, это работает gr8 ....... это решение :-)
 14 июн. 2014 г., 22:56
Проблема, с которой я сталкиваюсь при таком подходе, состоит в том, что вы не получаете немедленного увеличения / уменьшения, если превышаете свои максимальные пределы. Как бы вы это исправить?
 TheTiger24 июл. 2012 г., 13:04
Я забыл принять ваш ответ ... извините за это, но теперь я принял :-)
 19 окт. 2012 г., 12:07
Спасибо, это действительно полезно
 15 июн. 2014 г., 04:30
@PaulSolt: Я бы хотел помочь вам с этой проблемой, но у меня больше нет среды для тестирования. Не могли бы вы задать новый вопрос?

view.transform пока вы зажимаете, вы можете видеть координацию вашего изображения, которая увеличивается и уменьшается. Таким образом, эти решения не работают так, как я ожидал. Я сделал свое решение таким образом;

Obj-C Version
    - (void)handlePinchGesture:(UIPinchGestureRecognizer *)recognizer {

        [recognizer.view setTransform:CGAffineTransformScale(recognizer.view.transform, 
recognizer.scale, recognizer.scale)];

        if (recognizer.view.transform.a > 1.6) {

            CGAffineTransform fooTransform = recognizer.view.transform;
            fooTransform.a = 1.6; // this is x coordinate
            fooTransform.d = 1.6; // this is y coordinate
            recognizer.view.transform = fooTransform;
        }

        if (recognizer.view.transform.a < 0.95) {

            CGAffineTransform fooTransform = recognizer.view.transform;
            fooTransform.a = 0.95; // this is x coordinate
            fooTransform.d = 0.95; // this is y coordinate
            recognizer.view.transform = fooTransform;
        }
        recognizer.scale = 1.0;
    }
Swift Version
func handlePinchGesture(recognizer: UIPinchGestureRecognizer) {

        if let view = recognizer.view {
            view.transform = CGAffineTransformScale(view.transform,
                recognizer.scale, recognizer.scale)
            if CGFloat(view.transform.a) > 1.6 {
                view.transform.a = 1.6 // this is x coordinate
                view.transform.d = 1.6 // this is x coordinate
            }
            if CGFloat(view.transform.d) < 0.95 {
                view.transform.a = 0.95 // this is x coordinate
                view.transform.d = 0.95 // this is x coordinate
            }
            recognizer.scale = 1
        }
    }

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

if ((self.frame.size.width > IMAGE_MIN_SIZE) && (self.frame.size.height > IMAGE_MIN_SIZE) && (self.frame.size.width < IMAGE_MAX_SIZE) && (self.frame.size.height < IMAGE_MAX_SIZE)) {
    lastSizeTransform = self.transform;
}else {
    self.transform = lastSizeTransform;
}

Здесь self - это imageView.

 TheTiger09 июн. 2012 г., 08:05
привет, я попробовал это, но это не работает - может быть, я путаю с lastSizeTransform и originalTransform ... я объявляю эти переменные, как это CGAffineTransform lastSizeTransform; CGAffineTransform originalTransform; Это нормально ??
 09 июн. 2012 г., 08:10
привет :-), размер кадра вашего изображения изменяется после преобразования?
 TheTiger09 июн. 2012 г., 08:38
NSLog (@ & Quot;% F & Quot;, recognizer.scale); это меняется, но высота и ширина моего изображения остаются прежними ... единственное изменение - преобразование imageView, а не высота и ширина.
 TheTiger09 июн. 2012 г., 08:12
ха-ха - это будет минимальный минимальный минимум, а в последнем его размер был равен 0, можно сказать, невидим ... и все работает очень быстро, всего за 0,2-0,3 секунды
 09 июн. 2012 г., 08:17
не нужно оригинального преобразования. Первый nslog, чтобы подтвердить, что ваш кадр просмотра становится все меньше и меньше с помощью жеста. чем использовать этот код ... должно работать.
 – (void)handlePinchGesture:(UIPinchGestureRecognizer *)gestureRecognizer 
    {
        if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
        // Reset the last scale, necessary if there are multiple objects with different scales
        lastScale = [gestureRecognizer scale];
        }

        if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
        [gestureRecognizer state] == UIGestureRecognizerStateChanged) {

        CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@”transform.scale”] floatValue];

        // Constants to adjust the max/min values of zoom
        const CGFloat kMaxScale = 2.0;
        const CGFloat kMinScale = 1.0;

        CGFloat newScale = 1 –  (lastScale – [gestureRecognizer scale]); // new scale is in the range (0-1)
        newScale = MIN(newScale, kMaxScale / currentScale);
        newScale = MAX(newScale, kMinScale / currentScale);
        CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
        [gestureRecognizer view].transform = transform;

        lastScale = [gestureRecognizer scale];  // Store the previous scale factor for the next pinch gesture call
        }

    }
 26 авг. 2016 г., 06:07
Удачного кодирования :)
 26 авг. 2016 г., 06:03
Не волнуйтесь, дорогой, я уже использую этот код и успешно загрузил в Appstore всего за 1 месяц.
 25 авг. 2016 г., 23:02
Ваш код работает на меня, спасибо. Но у меня есть 1 сомнение в этом кодеCGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@”transform.scale”] floatValue]; Я думаю, что Apple отклонит проект с этим кодом, потому что я прочитал один раз, что доступ к членуvalueForKeyPath:@”transform.scale” Apple отклонить.
 09 июн. 2015 г., 11:16
Наслаждайся этим ....!!!!

Ваш ответ на вопрос