사용자가 내 응용 프로그램에서 표준 핀치 작업을 수행 할 때 UIImage 개체를 확대 / 축소하고 싶습니다. 해당 세부 사항이 어떤 식 으로든 도움이된다면 현재 UIImageView를 사용하여 이미지를 표시하고 있습니다.
나는 이것을하는 방법을 알아 내려고 노력하고 있지만 지금까지 그러한 운이 없습니다.
단서가 있습니까?
답변:
이를 수행하는 또 다른 쉬운 방법 UIImageView
은 UIScrollView
. 여기 에서 설명했듯이 스크롤 뷰의 contentSize를 UIImageView's
크기 와 동일하게 설정해야 합니다. 컨트롤러 인스턴스를 스크롤 뷰의 델리게이트로 설정하고 핀치 확대 및 이미지 패닝을 허용 하는 viewForZoomingInScrollView:
및 scrollViewDidEndZooming:withView:atScale:
메서드를 구현합니다 . 이것은 전체 웹보기의 오버 헤드가 없기 때문에 Ben의 솔루션이 약간 더 가벼운 방식으로 수행하는 작업입니다.
발생할 수있는 한 가지 문제는 스크롤 뷰 내의 크기 조정이 이미지에 적용된 변환 형식으로 제공된다는 것입니다. 이는 높은 줌 배율에서 흐릿함을 유발할 수 있습니다. 다시 그릴 수있는 항목의 경우 핀치 제스처가 완료된 후 더 선명한 디스플레이를 제공하기 위해 여기 에서 제 제안을 따를 수 있습니다 . 그 시점에서 hniels의 솔루션을 사용하여 이미지의 크기를 조정할 수 있습니다.
다른 사람들이 설명했듯이 가장 쉬운 해결책은 UIImageView를 UIScrollView에 넣는 것입니다. Interface Builder .xib 파일에서이 작업을 수행했습니다.
viewDidLoad에서 다음 변수를 설정합니다. 컨트롤러를 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;
}
확대 / 축소하려는 imageView를 반환하려면 다음 메서드를 구현해야합니다.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
iOS9 이전 버전에서는 다음과 같은 빈 델리게이트 메서드를 추가해야 할 수도 있습니다.
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
}
애플 문서는 이 작업을 수행하는 방법을 설명하는 좋은 일을한다 :
scrollViewDidEndZooming :
방법 없이 .
UIImageView에 대한 Shefali의 솔루션은 훌륭하게 작동하지만 약간의 수정이 필요합니다.
- (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;
}
}
(Shefali의 솔루션은 꼬집는 동안 연속적으로 확장되지 않는다는 단점이 있습니다. 또한 새 핀치를 시작할 때 현재 이미지 배율이 재설정되었습니다.)
아래 코드는 UIScrollView를 사용하지 않고 UIImageView를 확대 / 축소하는 데 도움이됩니다.
-(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;
}
}
절대로 UIImage
. 이제까지.
대신에의 확대 및 축소하고 view
그 표시합니다 UIImage
.
이 특정한 경우에, 당신은 사용자 정의 만들 수 chould UIView
A, 이미지를 표시하는 사용자 정의 그리기를 UIImageView
당신을 위해 이미지를 표시하는, 또는 UIWebView
몇 가지 추가적인 HTML을해야 할 것이다 그것을 백업 할 수 있습니다.
모든 경우에, 당신은 구현해야합니다 touchesBegan
, touchesMoved
그리고 같은 사용자가 (줌, 팬 등)을 수행하려고 결정 할 수 있습니다.
다음은 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;
}
이 기사는 Apple 지원 ( http://discussions.apple.com/message.jspa?messageID=7276709#7276709) 에서 찾을 수 있습니다.
Shafali 및 JRV의 답변은 패닝 및 핀치로 확대 / 축소를 포함하도록 확장되었습니다.
#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;
}
}
이 작업을 수행하는 가장 간단한 방법은 핀치 확대 / 축소 만 있으면 이미지를 내부에 배치하는 것입니다 UIWebView
(적은 양의 html 래퍼 코드를 작성하고 이미지를 참조하면 기본적으로 완료됩니다). 이 작업을 수행하는 더 complcated 방법은 사용하는 것입니다 touchesBegan
, touchesMoved
그리고 touchesEnded
사용자의 손가락을 추적하고보기의 적절 transform 속성을 조정합니다.
UIImage를 확대 / 축소하고 싶지 않습니다. 대신 UIImage View Controller가 포함 된 View를 확대 / 축소하십시오.
이 문제에 대한 해결책을 만들었습니다. 내 코드를 살펴보십시오.
@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()
}
주의 : PinchGestureRecognizer를 연결하는 것을 잊지 마십시오.