I am building a ViewController just to show one image. I added the ImageView programmatically to a scroll view. I would like to allow the user to zoom in and out. This is my code
#interface ImageViewerViewController ()<UIScrollViewDelegate>
#property (nonatomic, strong) UIImageView *ImageView;
#property (weak, nonatomic) IBOutlet UIScrollView *Scroll;
#end
#implementation ImageViewerViewController
-(UIView*) viewForZoomingInScrollView{
return self.ImageView;
}
-(void) viewDidLoad{
self.Scroll.minimumZoomScale = 0.2;
self.Scroll.maximumZoomScale = 1.5;
self.Scroll.delegate = self;
NSLog(#"View did load");
if(self.imageName)
[self updateImage];
}
-(void)setImageName:(NSString *)imageName{
NSLog(#"set Image");
_imageName = imageName;
}
-(void)updateImage{
self.ImageView =[[UIImageView alloc]init];
self.ImageView.image = [UIImage imageNamed:self.imageName];
[self.ImageView sizeToFit];
self.Scroll.contentSize = self.imageName? self.ImageView.image.size: CGSizeZero;
[self.Scroll addSubview:self.ImageView];
}
#end
As you see, I already set the delegate of the scroll to self and I added the protocol header and the needed message.
But the zooming feature is not working.
Could you help me please?
I appreciate your time and efforts.
Regards,
This will work as I created a demo of it. If anything do else let me know.
-(void)viewDidLoad
{
float minimumScale = [_floorPlanImageView frame].size.width /[_floorPlanScrollView frame].size.width;
_floorPlanScrollView.maximumZoomScale = 5; //Change as per you need
_floorPlanScrollView.minimumZoomScale = minimumScale; //Change as you need
_floorPlanScrollView.zoomScale = minimumScale;
_floorPlanScrollView.delegate =self;
_floorPlanScrollView.clipsToBounds = YES;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return _floorPlanImageView;
}
Related
My problem with after pinch zoom, when I pinch zoom and after drag image then white space on top and bottom.
My Code as per apple documentation.
https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/UIScrollView_pg/ZoomZoom/ZoomZoom.html
Sample code
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
scrollView.minimumZoomScale=0.5;
scrollView.maximumZoomScale=6.0;
scrollView.contentSize=CGSizeMake(1280, 960);
scrollView.delegate = self;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageView;
}
Thank you.
At first set your minimum zoom scale to 1.0:
scrollView.minimumZoomScale = 1.0;
Next, set the contentSize for scrollView:
scrollView.contentSize = [UIScreen mainScreen].bounds.size;
And if you don't want to see the extra space when bouncing, add the next line:
scrollView.bounces = NO;
Completely, the method should looks something like this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.scrollView.minimumZoomScale = 1.0;
self.scrollView.maximumZoomScale = 6.0;
self.scrollView.bounces = NO;
self.scrollView.contentSize = [UIScreen mainScreen].bounds.size;
self.scrollView.delegate = self;
}
Hope it will help.
This is how I do it. If you image fits perfectly into the view, there will be no white space when you zoom and pan.
If your image does not fit or scale properly, there will be white space on the sides OR the top.
First make sure your image is the correct size. Next you need to add minimumZoomScale and maximumZoomScale to the scrollView. The rest will work after that. You can use auto-layout or frames. Up to you.
This example uses auto-layout:
#import "ViewController.h"
#interface AutoLayoutScrollView : UIScrollView
#property (nonatomic, weak) UIView *contentView;
#end
#implementation AutoLayoutScrollView
- (instancetype)init {
if (self = [super init]) {
UIView *view = [[UIView alloc] init];
self.contentView = view;
[self addSubview:view];
[self.contentView.leftAnchor constraintEqualToAnchor:self.leftAnchor].active = YES;
[self.contentView.rightAnchor constraintEqualToAnchor:self.rightAnchor].active = YES;
[self.contentView.topAnchor constraintEqualToAnchor:self.topAnchor].active = YES;
[self.contentView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor].active = YES;
[self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
}
return self;
}
- (void)didMoveToSuperview {
[super didMoveToSuperview];
UIView *parent = self.superview;
if (parent) {
[self.leftAnchor constraintEqualToAnchor:parent.leftAnchor].active = YES;
[self.rightAnchor constraintEqualToAnchor:parent.rightAnchor].active = YES;
[self.topAnchor constraintEqualToAnchor:parent.topAnchor].active = YES;
[self.bottomAnchor constraintEqualToAnchor:parent.bottomAnchor].active = YES;
[self setTranslatesAutoresizingMaskIntoConstraints:NO];
}
}
#end
#interface ViewController () <UIScrollViewDelegate>
#property (nonatomic, strong) AutoLayoutScrollView *scrollView;
#property (nonatomic, strong) UIImageView *imageView;
#property (nonatomic, strong) UIPanGestureRecognizer *panGesture;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView = [[AutoLayoutScrollView alloc] init];
[self.view addSubview:self.scrollView];
[self.scrollView.contentView.widthAnchor constraintEqualToAnchor:self.view.widthAnchor].active = YES;
[self.scrollView.contentView.heightAnchor constraintEqualToAnchor:self.view.heightAnchor].active = YES;
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Image"]];
[self.imageView setContentMode:UIViewContentModeScaleAspectFit];
[self.scrollView.contentView addSubview:self.imageView];
[self.imageView.leftAnchor constraintEqualToAnchor:self.scrollView.contentView.leftAnchor].active = YES;
[self.imageView.rightAnchor constraintEqualToAnchor:self.scrollView.contentView.rightAnchor].active = YES;
[self.imageView.topAnchor constraintEqualToAnchor:self.scrollView.contentView.topAnchor].active = YES;
[self.imageView.bottomAnchor constraintEqualToAnchor:self.scrollView.contentView.bottomAnchor].active = YES;
[self.imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.scrollView setMinimumZoomScale:1.0];
[self.scrollView setMaximumZoomScale:3.0];
[self.scrollView setZoomScale:1.0f animated:YES];
[self.scrollView setDelegate:self];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
#end
UITapGestureRecognizer is not working with my UIImageView Class on my UIViewController.
HousePictureView *pictureHouse = [[HousePictureView alloc] init:[dictionary objectForKey:#"photo_url"]];
UITapGestureRecognizer *picturestap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showpictures)];
picturestap.numberOfTapsRequired = 1;
[pictureHouse addGestureRecognizer:picturestap];
[parentScroll addSubview:pictureHouse];
HousePictureView.m
#interface HousePictureView() {
CGFloat screenwidth;
}
#property (strong, nonatomic) UIImageView *pictureView;
#end
#implementation HousePictureView
-(id)init:(NSString*)url
{
screenwidth = [UIScreen mainScreen].bounds.size.width; // Width of this screen
if(self = [super init])
{
_pictureView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,screenwidth,300)];
[_pictureView setImageWithURL:[NSURL URLWithString:url] placeholderImage:[Functions resizeImage:[UIImage imageNamed:#"nophoto"] newSize:CGSizeMake(screenwidth,300)]];
_pictureView.userInteractionEnabled = YES;
[self addSubview:_pictureView];
}
return self;
}
#end
HousePictureView.h
#interface HousePictureView : UIImageView
- (id)init:(NSString*)url;
#end
Why does it not possible to have an event while userInteractionEnabled form views parents are activated?
Thank you for your help :)
mmmhhh you have created an UIImageView custom class with a property UIImageView added like a subview. Why?
Just use "self".
It does not work because you're adding a tap gesture on a UIImageView that is under another.
I have made a demo for zoom image using UIScrollView. My ViewController only contains one image.
The problem is the image cannot zoom in iO7 (I have tested on iPhone4S-iOS7) but work perfectly in iOS8/iOS9.
Any ideas on how to fix it?
Here is my code
#import "ViewController.h"
#interface ViewController ()<UIScrollViewDelegate>
#property (weak, nonatomic) IBOutlet UIScrollView *scrollview;
#property (weak, nonatomic) IBOutlet UIView *contentview;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
float minimumScale = [_contentview frame].size.width /[_scrollview frame].size.width;
_scrollview.maximumZoomScale = 5; //Change as per you need
_scrollview.minimumZoomScale = minimumScale; //Change as you need
_scrollview.zoomScale = minimumScale;
_scrollview.delegate =self;
_scrollview.clipsToBounds = YES;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return self.contentview;
}
#end
Here is the layout structure
Screen.png constraint
ContentView constraint
ScrollView constraint
Here is my demo project
https://drive.google.com/file/d/0B679aXO0SBmMeUVHTUdOcmxJSXM/view
The height and width constraints are causing this in iOS 7. A workaround would be, removing those constraints for iOS 7 and calculate minimumScale manually. in IOS 8 and above, do not change anything.
- (void)viewDidLoad {
[super viewDidLoad];
float minimumScale = 1;
if (floor(NSFoundationVersionNumber) < NSFoundationVersionNumber_iOS_8_0) {
[self.view removeConstraints:self.heightWidthConstraints];
minimumScale = self.scrollview.frame.size.width / self.imageView.image.size.width;
}
_scrollview.maximumZoomScale = 5; //Change as per you need
_scrollview.minimumZoomScale = minimumScale; //Change as you need
//_scrollview.zoomScale = minimumScale;
_scrollview.delegate = self;
//_scrollview.clipsToBounds = YES;
[self.scrollview setZoomScale:minimumScale animated:YES];
}
Remove width and height contraint of contentView.
Add centralHorizontal constraint of contentView with scrollView
Let me know if it works.
I have a UIView that I am using as a simple onboarding view. I simply shows n images, that the user can swipe through.
The only image that loads is the very first image "OnBoard-1". The other images are there when I debug the what is being added to the image view.
What am I doing wrong?
.h
#import <UIKit/UIKit.h>
#interface OnBoardingView : UIView
- (void)setImages:(NSArray *)newImages;
#end
Here is the .m file
#import "OnBoardingView.h"
#interface OnBoardingView () <UIScrollViewDelegate>
{
UIPageControl *pageControl;
NSArray *contentImages;
}
#property (nonatomic, retain) UIPageControl *pageControl;
#property (nonatomic, retain) NSArray *contentImages;
#end
#implementation OnBoardingView
#synthesize pageControl;
#synthesize contentImages;
- (id) initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) { }
return self;
}
#pragma mark - Override contentImages setter
- (void)setImages:(NSArray *)newImages {
if (newImages != self.contentImages) {
self.contentImages = newImages;
[self setup];
}
}
#pragma mark - Carousel setup
- (void)setup {
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
[scrollView setDelegate:self];
[scrollView setShowsHorizontalScrollIndicator:NO];
[scrollView setPagingEnabled:YES];
[scrollView setBounces:NO];
CGSize scrollViewSize = scrollView.frame.size;
for (NSInteger i = 0; i < [self.contentImages count]; i++) {
CGRect slideRect = CGRectMake(scrollViewSize.width * i, 0, scrollViewSize.width, scrollViewSize.height);
UIView *slide = [[UIView alloc] initWithFrame:slideRect];
[slide setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0]];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.frame];
[imageView setImage:[UIImage imageNamed:[self.contentImages objectAtIndex:i]]];
NSLog(#"Image named: %#", [self.contentImages objectAtIndex:i]);
[slide addSubview:imageView];
[scrollView addSubview:slide];
}
UIPageControl *tempPageControll = [[UIPageControl alloc] initWithFrame:CGRectMake(0, scrollViewSize.height - 20, scrollViewSize.width, 20)];
[self setPageControl:tempPageControll];
[self.pageControl setNumberOfPages:[self.contentImages count]];
[scrollView setContentSize:CGSizeMake(scrollViewSize.width * [self.contentImages count], scrollViewSize.height)];
[self addSubview:scrollView];
[self addSubview:self.pageControl];
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
[self.pageControl setCurrentPage:page];
}
#end
You initialise the imageView with the frame of the scrollView, that's in any case not right and may be the cause of your problem.
BTW:
Your property handling looks a bit strange (why the synthesizing instead of just using a normal property only?), and why do you compare the arrays by pointer (newImages != self.contentImages)?
If you want to show the images in paging directly you can assign the number of pages count.And apply the swipe gesture(left and right) to imageview.And based on left and right swipe,you can change the image of imageview.
I want to show an image using a UIImageView inside a UIScrollview. The image needs to fit on the screen while keeping the aspect ratio.
This all works, except that, when I zoom first, I can scroll below the image. The height of area is about 64.
This is how it looks after scrolling (White is the background color of the UIImageView and red is the background color of the UIScrollView):
This is the code in my ImageViewController:
#import "ImageViewController.h"
#interface ImageViewController () <UIScrollViewDelegate>
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) UIImageView *imageView;
#property (nonatomic, strong) UIImage *image;
#end
#implementation ImageViewController
- (void)viewDidLoad
{
NSLog(#"viewDidLoad");
[super viewDidLoad];
_scrollView.minimumZoomScale = 1.0 ;
_scrollView.maximumZoomScale = _imageView.image.size.width / _scrollView.frame.size.width;
_scrollView.zoomScale = 1.0;
_scrollView.backgroundColor = [UIColor redColor];
_scrollView.delegate = self;
_imageView.backgroundColor = [UIColor whiteColor];
[_scrollView addSubview:_imageView];
}
- (void)viewDidLayoutSubviews
{
self.imageView.frame = self.scrollView.bounds;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.imageView setContentMode:UIViewContentModeScaleAspectFit];
}
- (UIImageView *)imageView
{
if (!_imageView) _imageView = [[UIImageView alloc] init];
return _imageView;
}
- (UIImage *)image
{
NSLog(#"image");
return self.imageView.image;
}
- (void)setImage:(UIImage *)image
{
NSLog(#"setImage");
self.imageView.image = image;
}
#pragma mark - UIScrollViewDelegate
// mandatory zooming method in UIScrollViewDelegate protocol
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
-(void)setImageURL:(NSURL *)imageURL
{
NSLog(#"setImageURL");
_imageURL = imageURL;
self.image = [UIImage imageWithContentsOfFile:[imageURL path]];
}
#end
This are the properties of my UIScrollView:
How can I fix this?
I got it working. This is my code:
#import "ImageViewController.h"
#interface ImageViewController () <UIScrollViewDelegate>
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) UIImageView *imageView;
#property (nonatomic, strong) UIImage *image;
#end
#implementation ImageViewController
- (void)viewDidLoad
{
NSLog(#"viewDidLoad");
[super viewDidLoad];
self.scrollView.contentSize = self.scrollView.frame.size;
self.scrollView.delegate = self;
CGRect rect = CGRectZero;
rect.size = self.image.size;
self.scrollView.minimumZoomScale = 0.5;
self.scrollView.maximumZoomScale = 2.5;
self.scrollView.zoomScale = 1.0;
self.imageView = [[UIImageView alloc] initWithFrame:rect];
self.imageView.image = self.image;
[self.scrollView addSubview:self.imageView];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
}
- (IBAction)tappedAction:(id)sender {
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:#[self.image] applicationActivities:nil];
[self presentViewController:activityVC animated:YES completion:nil];
}
- (void)viewDidLayoutSubviews
{
self.imageView.frame = self.scrollView.bounds;
}
#pragma mark - UIScrollViewDelegate
// mandatory zooming method in UIScrollViewDelegate protocol
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
UIView *subView = [scrollView.subviews objectAtIndex:0];
CGFloat offsetX = MAX((scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5, 0.0);
CGFloat offsetY = MAX((scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5, 0.0);
subView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
scrollView.contentSize.height * 0.5 + offsetY);
}
-(void)setImageURL:(NSURL *)imageURL
{
NSLog(#"setImageURL");
_imageURL = imageURL;
self.image = [UIImage imageWithContentsOfFile:[imageURL path]];
}
#end
The code in scrollViewDidZoom: is used to keep the image centered.