Domanda

Vorrei ingrandire / rimpicciolire un oggetto UIImage quando l'utente esegue l'azione di pizzicamento standard sulla mia applicazione. Attualmente sto usando un UIImageView per visualizzare la mia immagine, se quel dettaglio aiuta in qualche modo.

Sto cercando di capire come farlo, ma finora non ho avuto fortuna.

Qualche indizio?

È stato utile?

Soluzione

Un altro modo semplice per farlo è quello di inserire il vostro UIImageView all'interno di un UIScrollView. Come descrivo qui , tu necessario impostare contentSize della vista di scorrimento per essere lo stesso del vostro UIImageView's dimensioni. Imposta l'istanza del tuo controller come delegato della vista di scorrimento e implementa i metodi viewForZoomingInScrollView: e scrollViewDidEndZooming:withView:atScale: per consentire lo zoom con pizzico e la panoramica delle immagini. Questo è effettivamente ciò che fa la soluzione di Ben, solo in modo leggermente più leggero, poiché non si ha il sovraccarico di una visualizzazione Web completa.

Un problema che potresti riscontrare è che il ridimensionamento all'interno della vista di scorrimento si presenta sotto forma di trasformazioni applicate all'immagine. Ciò può comportare sfocatura ad alti fattori di zoom. Per qualcosa che può essere ridisegnato, puoi seguire i miei suggerimenti qui per fornire una visualizzazione più nitide, dopo il gesto pizzico è finito. soluzione hniels' potrebbe essere utilizzato in quel punto per ridimensionare l'immagine.

Altri suggerimenti

Come altri hanno descritto, la soluzione più semplice è quella di inserire UIImageView in UIScrollView. L'ho fatto nel file .xib di Interface Builder.

In viewDidLoad, imposta le seguenti variabili. Imposta il tuo controller come UIScrollViewDelegate.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.scrollView.minimumZoomScale = 0.5;
    self.scrollView.maximumZoomScale = 6.0;
    self.scrollView.contentSize = self.imageView.frame.size;
    self.scrollView.delegate = self;
}

È necessario implementare il seguente metodo per restituire l'immagine che si desidera ingrandire.

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.imageView;
}

Nelle versioni precedenti a iOS9, potrebbe essere necessario aggiungere anche questo metodo delegato vuoto:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
}

La Documentazione Apple fa un buon lavoro nel descrivere come fare:

La soluzione di Shefali per UIImageView funziona alla grande, ma ha bisogno di una piccola modifica:

- (void)pinch:(UIPinchGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateEnded
        || gesture.state == UIGestureRecognizerStateChanged) {
        NSLog(@"gesture.scale = %f", gesture.scale);

        CGFloat currentScale = self.frame.size.width / self.bounds.size.width;
        CGFloat newScale = currentScale * gesture.scale;

        if (newScale < MINIMUM_SCALE) {
            newScale = MINIMUM_SCALE;
        }
        if (newScale > MAXIMUM_SCALE) {
            newScale = MAXIMUM_SCALE;
        }

        CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale);
        self.transform = transform;
        gesture.scale = 1;
    }
}
(p

Il codice seguente aiuta a ingrandire UIImageView senza usare UIScrollView:

-(void)HandlePinch:(UIPinchGestureRecognizer*)recognizer{
    if ([recognizer state] == UIGestureRecognizerStateEnded) {
        NSLog(@"======== Scale Applied ===========");
        if ([recognizer scale]<1.0f) {
            [recognizer setScale:1.0f];
        }
        CGAffineTransform transform = CGAffineTransformMakeScale([recognizer scale],  [recognizer scale]);
        imgView.transform = transform;
    }
}

Tieni presente che non stai MAI ingrandendo un UIImage. MAI.

Invece, stai ingrandendo e rimpicciolendo il view che visualizza UIView.

In questo caso particolare, devi scegliere di creare un UIImageView personalizzato con disegno personalizzato per visualizzare l'immagine, un UIWebView che visualizza l'immagine per te o un touchesBegan che avrà bisogno di un po 'di HTML aggiuntivo sul retro su.

In tutti i casi, dovrai implementare touchesMoved, <=> e simili per determinare cosa l'utente sta cercando di fare (zoom, pan, ecc.).

Ecco una soluzione che ho usato prima che non richiede l'utilizzo di UIWebView.

- (UIImage *)scaleAndRotateImage(UIImage *)image
{
    int kMaxResolution = 320; // Or whatever

    CGImageRef imgRef = image.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);


    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);
    if (width > kMaxResolution || height > kMaxResolution) {
        CGFloat ratio = width/height;
        if (ratio > 1) {
            bounds.size.width = kMaxResolution;
            bounds.size.height = bounds.size.width / ratio;
        }
        else {
            bounds.size.height = kMaxResolution;
            bounds.size.width = bounds.size.height * ratio;
        }
    }

    CGFloat scaleRatio = bounds.size.width / width;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = image.imageOrientation;
    switch(orient) {

        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);
        CGContextTranslateCTM(context, -height, 0);
    }
    else {
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy;
}

L'articolo è disponibile sul supporto Apple all'indirizzo: http://discussions.apple.com/message.jspa?messageID=7276709# 7276709

Le risposte di Shafali e JRV sono state estese per includere panoramica e pizzicare per ingrandire:

#define MINIMUM_SCALE 0.5
#define MAXIMUM_SCALE 6.0
@property CGPoint translation;


- (void)pan:(UIPanGestureRecognizer *)gesture {
    static CGPoint currentTranslation;
    static CGFloat currentScale = 0;
    if (gesture.state == UIGestureRecognizerStateBegan) {
        currentTranslation = _translation;
        currentScale = self.view.frame.size.width / self.view.bounds.size.width;
    }
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {

        CGPoint translation = [gesture translationInView:self.view];

        _translation.x = translation.x + currentTranslation.x;
        _translation.y = translation.y + currentTranslation.y;
        CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x , _translation.y);
        CGAffineTransform transform2 = CGAffineTransformMakeScale(currentScale, currentScale);
        CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
        self.view.transform = transform;
    }
}


- (void)pinch:(UIPinchGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {
//        NSLog(@"gesture.scale = %f", gesture.scale);

        CGFloat currentScale = self.view.frame.size.width / self.view.bounds.size.width;
        CGFloat newScale = currentScale * gesture.scale;

        if (newScale < MINIMUM_SCALE) {
            newScale = MINIMUM_SCALE;
        }
        if (newScale > MAXIMUM_SCALE) {
            newScale = MAXIMUM_SCALE;
        }

        CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x, _translation.y);
        CGAffineTransform transform2 = CGAffineTransformMakeScale(newScale, newScale);
        CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
        self.view.transform = transform;
        gesture.scale = 1;
    }
}

Il modo più semplice per farlo, se tutto ciò che vuoi è lo zoom con pizzico, è quello di posizionare la tua immagine all'interno di un UIWebView (scrivi una piccola quantità di codice wrapper html, fai riferimento alla tua immagine e il gioco è fatto). Il modo più complice per farlo è usare touchesBegan, touchesMoved e touchesEnded per tenere traccia delle dita dell'utente e regolare la proprietà di trasformazione della vista in modo appropriato.

Tieni presente che non vuoi ingrandire / ridurre UIImage. Prova invece a ingrandire / ridurre la vista che contiene UIImage View Controller.

Ho creato una soluzione per questo problema. Dai un'occhiata al mio codice:

@IBAction func scaleImage(sender: UIPinchGestureRecognizer) {
        self.view.transform = CGAffineTransformScale(self.view.transform, sender.scale, sender.scale)
        sender.scale = 1
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        view.backgroundColor = UIColor.blackColor()
    }

N.B .: Non dimenticare di collegare PinchGestureRecognizer.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top