Leaks in my UIScrollView helper class - ios

I want to publish tutorial about how to easily create an UIScrollView on http://www.xprogress.com/ and I just want to check with you guys if the code is alright before I publish anything. Any help will be appreciated and I'll put your name / website on the bottom of the article :)
Thanks a lot :)
Ondrej
header file:
///
/// IGUIScrollViewImage.h
///
/// IGUILibrary
///
/// Created by Ondrej Rafaj on 7.4.10.
///
/// Copyright 2010 Home. All rights reserved.
///
/// #todo enable margin and center the image to the middle of the view
/**
<b>Examples:</b>
<i>This is just a short example how to use this class</i>
<pre>
- (NSArray *)getImages {
NSMutableArray *arr = [[[NSMutableArray alloc] init] autorelease];
[arr addObject:[UIImage imageNamed:#"image-1.jpg"]];
[arr addObject:[UIImage imageNamed:#"image-2.png"]];
[arr addObject:[UIImage imageNamed:#"image-3.png"]];
[arr addObject:[UIImage imageNamed:#"image-4.jpg"]];
return (NSArray *)arr;
}
- (void)viewDidLoad {
IGUIScrollViewImage *svimage = [[IGUIScrollViewImage alloc] init];
[svimage setSizeFromScrollView:self.scrView]; // takes size of the scroll view you've already placed on stage via Interface Builder
// or
//[svimage setWidth:320 andHeight:240]; // half screen
[svimage enablePositionMemory]; // enables position (pagination) memory for this scroll view
// or
//[svimage enablePositionMemoryWithIdentifier:#"myIdentifier"]; if you have more instances of this scroll view in your application
[svimage enablePageControlOnBottom];
// or
//[svimage enablePageControlOnTop];
[self.myUIView addSubview:[svimage get]]; // and place it on the stage :)
[super viewDidLoad];
}
</pre>
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface IGUIScrollViewImage : NSObject <UIScrollViewDelegate> {
UIScrollView *scrollView;
UIPageControl *pageControl;
CGRect rectScrollView;
CGRect rectPageControl;
int scrollWidth;
int scrollHeight;
NSArray *contentArray;
UIColor *bcgColor;
BOOL pageControlEnabledTop;
BOOL pageControlEnabledBottom;
BOOL rememberPosition;
NSString *positionIdentifier;
}
#property (nonatomic, retain) UIScrollView *scrollView;
- (int)getScrollViewWidth;
- (void)setWidth:(int)width andHeight:(int)height;
- (void)setSizeFromScrollView:(UIScrollView *)scView;
- (void)setBackGroudColor:(UIColor *)color;
- (void)setContentArray:(NSArray *)images;
- (void)enablePageControlOnTop;
- (void)enablePageControlOnBottom;
- (void)enablePositionMemory;
- (void)enablePositionMemoryWithIdentifier:(NSString *)identifier;
- (UIScrollView *)getWithPosition:(int)page;
- (UIScrollView *)getWithPositionMemoryIdentifier:(NSString *)identifier;
- (UIScrollView *)get;
#end
And the implementation file:
//
// IGUIScrollViewImage.m
// IGUILibrary
//
// Created by Ondrej Rafaj on 7.4.10.
// Copyright 2010 Home. All rights reserved.
//
#import "IGUIScrollViewImage.h"
#define kIGUIScrollViewImagePageIdentifier #"kIGUIScrollViewImagePageIdentifier"
#define kIGUIScrollViewImageDefaultPageIdentifier #"Default"
#implementation IGUIScrollViewImage
#synthesize scrollView;
- (int)getScrollViewWidth {
return ([contentArray count] * scrollWidth);
}
- (void)setWidth:(int)width andHeight:(int)height {
scrollWidth = width;
scrollHeight = height;
if (!width || !height) rectScrollView = [[UIScreen mainScreen] applicationFrame];
else rectScrollView = CGRectMake(0, 0, width, height);
}
- (void)setSizeFromScrollView:(UIScrollView *)scView {
scrollWidth = scView.frame.size.width;
scrollHeight = scView.frame.size.height;
rectScrollView = CGRectMake(0, 0, scrollWidth, scrollHeight);
}
- (void)setContentArray:(NSArray *)images {
contentArray = images;
}
- (void)setBackGroudColor:(UIColor *)color {
bcgColor = color;
}
- (void)enablePageControlOnTop {
pageControlEnabledTop = YES;
}
- (void)enablePageControlOnBottom {
pageControlEnabledBottom = YES;
}
- (void)enablePositionMemoryWithIdentifier:(NSString *)identifier {
rememberPosition = YES;
if (!identifier) identifier = kIGUIScrollViewImageDefaultPageIdentifier;
positionIdentifier = identifier;
}
- (void)enablePositionMemory {
[self enablePositionMemoryWithIdentifier:nil];
}
- (UIScrollView *)getWithPosition:(int)page {
if (!contentArray) {
contentArray = [[[NSArray alloc] init] autorelease];
}
if (page > [contentArray count]) page = 0;
if (!scrollWidth || !scrollHeight) {
rectScrollView = [[UIScreen mainScreen] applicationFrame];
scrollWidth = rectScrollView.size.width;
scrollHeight = rectScrollView.size.height;
}
rectScrollView = CGRectMake(0, 0, scrollWidth, scrollHeight);
self.scrollView = [[UIScrollView alloc] initWithFrame:rectScrollView];
self.scrollView.contentSize = CGSizeMake([self getScrollViewWidth], scrollHeight);
if (!bcgColor) bcgColor = [UIColor blackColor];
self.scrollView.backgroundColor = bcgColor;
self.scrollView.alwaysBounceHorizontal = YES;
self.scrollView.contentOffset = CGPointMake(page * scrollWidth, 0);
self.scrollView.pagingEnabled = YES;
UIImageView *imageView;
UIView *main = [[[UIView alloc] initWithFrame:rectScrollView] autorelease];
int i = 0;
for (UIImage *img in contentArray) {
imageView = [[UIImageView alloc] initWithImage:img];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
imageView.backgroundColor = [UIColor blackColor];
float ratio = img.size.width/rectScrollView.size.width;
CGRect imageFrame = CGRectMake(i, 0, rectScrollView.size.width, (img.size.height / ratio));
imageView.frame = imageFrame;
[self.scrollView addSubview:imageView];
i += scrollWidth;
}
[imageView release];
[main addSubview:scrollView];
if (pageControlEnabledTop) {
rectPageControl = CGRectMake(0, 5, scrollWidth, 15);
}
else if (pageControlEnabledBottom) {
rectPageControl = CGRectMake(0, (scrollHeight - 25), scrollWidth, 15);
}
if (pageControlEnabledTop || pageControlEnabledBottom) {
pageControl = [[[UIPageControl alloc] initWithFrame:rectPageControl] autorelease];
pageControl.numberOfPages = [contentArray count];
pageControl.currentPage = page;
[main addSubview:pageControl];
}
if (pageControlEnabledTop || pageControlEnabledBottom || rememberPosition) self.scrollView.delegate = self;
//if (margin) [margin release];
return (UIScrollView *)main;
}
- (UIScrollView *)get {
return [self getWithPosition:0];
}
- (UIScrollView *)getWithPositionMemoryIdentifier:(NSString *)identifier {
[self enablePositionMemoryWithIdentifier:identifier];
return [self getWithPosition:[[[NSUserDefaults alloc] objectForKey:[NSString stringWithFormat:#"%#%#", kIGUIScrollViewImagePageIdentifier, positionIdentifier]] intValue]];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sv {
int page = sv.contentOffset.x / sv.frame.size.width;
pageControl.currentPage = page;
if (rememberPosition) {
[[NSUserDefaults alloc] setObject:[NSString stringWithFormat:#"%d", page] forKey:[NSString stringWithFormat:#"%#%#", kIGUIScrollViewImagePageIdentifier, positionIdentifier]];
}
}
- (void)dealloc {
[scrollView release];
[super dealloc];
}
#end

Just a quick glance. You alloc UIImageView multiple times in
-(UIScrollView*)getWithPosition:(int)page and release it only once:
for (UIImage *img in contentArray) {
imageView = [[UIImageView alloc] initWithImage:img];
// ...
}
[imageView release];

Related

Detect button click event on customcell

I have added a custom cell as follows for stepper progress. UI perspective, it looks what I want, but I could not able to figure out how I could able to determine whether or not button has been clicked.
I have inspired via https://github.com/yenbekbay/AYStepperView, but this one has PageViewController which I could not able to add it in the tableCell.
#import "StepperProgressTableViewCell.h"
#import "AYStepperView.h"
static CGFloat const kFormStepperViewHeight = 80;
#interface StepperProgressTableViewCell ()
#property (nonatomic) AYStepperView *stepperView;
#property (nonatomic) NSUInteger currentIndex;
#property (nonatomic) NSUInteger currentStep;
#end
#implementation StepperProgressTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
[self setUpViews];
self.currentIndex = 0;
self.currentStep = 0;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
}
#pragma mark Private
- (void)setUpViews {
self.stepperView = [[AYStepperView alloc]initWithFrame:CGRectMake(0, 40 , self.frame.size.width, kFormStepperViewHeight)
titles:#[NSLocalizedString(#"Start", nil),
NSLocalizedString(#"Cooking", nil),
NSLocalizedString(#"Ready", nil)]];
self.stepperView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
self.stepperView.userInteractionEnabled = YES;
[self addSubview:self.stepperView];
self.containerView = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.stepperView.frame), CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - CGRectGetMaxY(self.stepperView.frame))];
[self addSubview:self.containerView];
}
#end
AYStepperView.m
#import "AYStepperView.h"
#import <pop/POP.h>
static UIEdgeInsets const kStepperViewPadding = {
15, 0, 15, 0
};
static CGFloat const kStepperLabelsSpacing = 10;
static CGFloat const kStepperPipeHeight = 5;
#interface AYStepperView ()
#property (nonatomic) UIView *pipeView;
#property (nonatomic) UIView *labelsView;
#property (nonatomic) UIView *pipeBackgroundView;
#property (nonatomic) UIView *pipeFillView;
#property (nonatomic) NSMutableArray *stepLabels;
#end
#implementation AYStepperView
#pragma mark Initialization
- (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)titles {
self = [super initWithFrame:frame];
if (!self) {
return nil;
}
_titles = titles;
self.backgroundColor = [UIColor colorWithRed:0.98f green:0.98f blue:0.98f alpha:1];
self.tintColor = [UIColor colorWithRed:0.2f green:0.29f blue:0.37f alpha:1];
self.pipeView = [[UIView alloc] initWithFrame:CGRectMake(kStepperViewPadding.left, kStepperViewPadding.top, CGRectGetWidth(self.bounds) - kStepperViewPadding.left - kStepperViewPadding.right, CGRectGetHeight(self.bounds) / 2 - kStepperViewPadding.top)];
[self addSubview:self.pipeView];
self.labelsView = [[UIView alloc] initWithFrame:CGRectMake(kStepperViewPadding.left, CGRectGetMaxY(self.pipeView.frame) + kStepperViewPadding.top, CGRectGetWidth(self.bounds) - kStepperViewPadding.left - kStepperViewPadding.right, CGRectGetHeight(self.bounds) / 2 - kStepperViewPadding.top - kStepperViewPadding.bottom)];
[self addSubview:self.labelsView];
self.pipeBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, (CGRectGetHeight(self.pipeView.bounds) - kStepperPipeHeight) / 2, CGRectGetWidth(self.pipeView.bounds), kStepperPipeHeight)];
self.pipeBackgroundView.backgroundColor = [UIColor lightGrayColor];
[self.pipeView addSubview:self.pipeBackgroundView];
CGRect pipeFillViewFrame = self.pipeBackgroundView.frame;
pipeFillViewFrame.size.width = 0;
self.pipeFillView = [[UIView alloc] initWithFrame:pipeFillViewFrame];
self.pipeFillView.backgroundColor = self.tintColor;
[self.pipeView addSubview:self.pipeFillView];
_stepButtons = [NSMutableArray new];
_stepLabels = [NSMutableArray new];
for (NSUInteger i = 0; i < titles.count; i++) {
UIButton *stepButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, CGRectGetHeight(self.pipeView.bounds), CGRectGetHeight(self.pipeView.bounds))];
stepButton.center = CGPointMake(CGRectGetWidth(self.pipeView.bounds) * (i + 0.5f) / titles.count, stepButton.center.y);
stepButton.clipsToBounds = YES;
stepButton.tag = i;
stepButton.layer.cornerRadius = CGRectGetHeight(stepButton.bounds) / 2;
stepButton.backgroundColor = [UIColor lightGrayColor];
[self.pipeView addSubview:stepButton];
[self.stepButtons addObject:stepButton];
UILabel *stepLabel = [UILabel new];
stepLabel.font = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]];
stepLabel.textColor = self.tintColor;
stepLabel.textAlignment = NSTextAlignmentCenter;
stepLabel.text = titles[i];
stepLabel.numberOfLines = 0;
stepLabel.frame = (CGRect) {
stepLabel.frame.origin, [stepLabel sizeThatFits:CGSizeMake(CGRectGetWidth(self.pipeView.bounds) / titles.count - kStepperLabelsSpacing, 0)]
};
stepLabel.center = CGPointMake(CGRectGetWidth(self.labelsView.bounds) * (i + 0.5f) / titles.count, CGRectGetHeight(self.labelsView.bounds) / 2);
[self.labelsView addSubview:stepLabel];
[self.stepLabels addObject:stepLabel];
}
_currentStepIndex = 0;
[self completeStepAtIndex:0 until:1 completionBlock:nil];
return self;
}
#pragma mark Public
- (void)updateCurrentStepIndex:(NSUInteger)currentStepIndex completionBlock:(void (^)())completionBlock {
if (currentStepIndex >= self.titles.count || currentStepIndex == self.currentStepIndex) {
if (completionBlock) {
completionBlock();
}
} else {
NSUInteger previousStepIndex = self.currentStepIndex;
_currentStepIndex = currentStepIndex;
if ((NSInteger)currentStepIndex - (NSInteger)previousStepIndex > 0) {
[self completeStepAtIndex:previousStepIndex + 1 until:currentStepIndex + 1 completionBlock:completionBlock];
} else {
[self uncompleteStepAtIndex:previousStepIndex until:currentStepIndex - 1 completionBlock:completionBlock];
}
}
}
#pragma mark Setters
- (void)setTintColor:(UIColor *)tintColor {
_tintColor = tintColor;
self.pipeFillView.backgroundColor = tintColor;
for (UILabel *label in self.stepLabels) {
label.textColor = tintColor;
}
[self.stepButtons[self.currentStepIndex] setBackgroundColor:tintColor];
}
#pragma mark Private
- (void)completeStepAtIndex:(NSUInteger)index until:(NSUInteger)until completionBlock:(void (^)())completionBlock {
if (index == until) {
if (completionBlock) {
completionBlock();
}
} else {
[UIView animateWithDuration:0.2f animations:^{
CGRect pipeFillViewFrame = self.pipeFillView.frame;
NSLog(#"%lu, %lu",until, index);
if(index == _titles.count - 1)
{
pipeFillViewFrame.size.width = CGRectGetWidth(self.pipeBackgroundView.bounds) * (index + 1.0f) / self.titles.count;
}
else
{
pipeFillViewFrame.size.width = CGRectGetWidth(self.pipeBackgroundView.bounds) * (index + 0.5f) / self.titles.count;
}
self.pipeFillView.frame = pipeFillViewFrame;
} completion:^(BOOL finishedWidthAnimation) {
[self completeStepAtIndex:index + 1 until:until completionBlock:completionBlock];
UIView *stepButton = self.stepButtons[index];
stepButton.backgroundColor = self.tintColor;
POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.velocity = [NSValue valueWithCGSize:CGSizeMake(3.f, 3.f)];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
scaleAnimation.springBounciness = 5.f;
[stepButton.layer pop_addAnimation:scaleAnimation forKey:#"scaleAnimation"];
}];
}
}
- (void)uncompleteStepAtIndex:(NSUInteger)index until:(NSUInteger)until completionBlock:(void (^)())completionBlock {
if (index == until) {
if (completionBlock) {
completionBlock();
}
} else {
if (index > until + 1) {
UIView *stepButton = self.stepButtons[index];
stepButton.backgroundColor = [UIColor lightGrayColor];
POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.velocity = [NSValue valueWithCGSize:CGSizeMake(3.f, 3.f)];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
scaleAnimation.springBounciness = 5.f;
[stepButton.layer pop_addAnimation:scaleAnimation forKey:#"scaleAnimation"];
}
[UIView animateWithDuration:0.2f animations:^{
CGRect pipeFillViewFrame = self.pipeFillView.frame;
pipeFillViewFrame.size.width = CGRectGetWidth(self.pipeBackgroundView.bounds) * (index + 0.5f) / self.titles.count;
self.pipeFillView.frame = pipeFillViewFrame;
} completion:^(BOOL finishedWidthAnimation) {
[self uncompleteStepAtIndex:index - 1 until:until completionBlock:completionBlock];
}];
}
}
#end
If you want to catch events from a cell to the view controller, the simplest way is to create a protocol and set the view controller as the cell's delegate. I'm sure there are many similar questions here that can help you like this one for example.

Symmetric zooming of image within scrollview in iOS

I am new to iPhone to iOS development. and I want a demo for zoom in and zoom out (symmetric zooming of image) a image within a scrollview in iOS.This is my code : in this code i have taken an image view within a scrollview(ZoomScrollView) and scrollview within a another Scrollview(scrollView_Gallery).Thanks in advance..
//ZoomGalleryViewController.m//
scrollView_Gallery.backgroundColor = [UIColor yellowColor];
scrollView_Gallery.delegate = self;
scrollView_Gallery.pagingEnabled = YES;
scrollView_Gallery.userInteractionEnabled = YES;
scrollView_Gallery.showsHorizontalScrollIndicator = NO;
scrollView_Gallery.showsVerticalScrollIndicator = NO;
[self.view addSubview:scrollView_Gallery];
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
{
[scrollView_Gallery setContentSize:CGSizeMake(self.view.frame.size.width*[arrayUrl count],self.view.frame.size.height)];
}
else if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
[scrollView_Gallery setContentSize:CGSizeMake([[UIScreen mainScreen] bounds].size.width*[arrayUrl count],[[UIScreen mainScreen] bounds].size.height)];
}
for (int i = 0; i < [arrayUrl count]; i++)
{
zoomScrollView = [[ZoomScrollView alloc]init];
zoomScrollView.backgroundColor = [UIColor redColor];
[zoomScrollView setContentSize:CGSizeMake(zoomScrollView.contentSize.width,zoomScrollView.frame.size.height)];
CGRect frame = scrollView_Gallery.frame;
frame.origin.x = (frame.size.width)* i;
frame.origin.y = 0;
zoomScrollView.frame = frame;
zoomScrollView.imageView.contentMode = UIViewContentModeScaleAspectFit;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[[arrayUrl objectAtIndex:i]objectForKey:#"photopath"]]];
__weak UIImageView *weakImageView = zoomScrollView.imageView;
zoomScrollView.imageView.tag = i;
zoomScrollView.ZOOM_VIEW_TAG = zoomScrollView.imageView.tag;
[zoomScrollView.imageView setImageWithURLRequest:request
placeholderImage:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image)
{
NSLog(#"image=%f,imageheight=%f",image.size.width,image.size.height);
UIImageView *strongImageView = weakImageView; // make local strong reference to protect against race conditions
strongImageView.frame = CGRectMake(0,0,image.size.width*image.scale, image.size.height*image.scale);
strongImageView.center = scrollView_Gallery.center;
NSLog(#"image11 = %f, imageheight11 = %f",image.size.width*image.scale, image.size.height*image.scale);
NSLog(#"imageScale = %f",image.scale);
if (!strongImageView) return;
[UIView transitionWithView:strongImageView
duration:0.3
options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
strongImageView.image = image;
}
completion:NULL];
//[scrollView_Gallery setContentOffset:CGPointMake(strongImageView.frame.size.width * (indexNumber+1), 0)];
}failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
NSLog(#"Request failed with error: %#", error);
}];
[scrollView_Gallery addSubview:zoomScrollView];
[zoomScrollView setContentSize:CGSizeMake(zoomScrollView.contentSize.width,zoomScrollView.frame.size.height)];
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
{
[scrollView_Gallery setContentOffset:CGPointMake(self.view.frame.size.width * (indexNumber), 0)];
}
else if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
[scrollView_Gallery setContentOffset:CGPointMake([[UIScreen mainScreen] bounds].size.width * (indexNumber), 0)];
}
// ZoomScrollView.h//
#import <UIKit/UIKit.h>
#interface MRZoomScrollView : UIScrollView <UIScrollViewDelegate>
{
UIImageView *imageView;
}
#property (nonatomic, retain) UIImageView *imageView;
#end
// MRZoomScrollView.m//
#import "MRZoomScrollView.h"
#define MRScreenWidth CGRectGetWidth([UIScreen mainScreen].applicationFrame)
#define MRScreenHeight CGRectGetHeight([UIScreen mainScreen].applicationFrame)
#interface MRZoomScrollView (Utility)
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center;
#end
#implementation MRZoomScrollView
#synthesize imageView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.delegate = self;
self.frame = CGRectMake(0, 0, MRScreenWidth, MRScreenHeight);
[self initImageView];
}
return self;
}
- (void)initImageView
{
imageView = [[UIImageView alloc]init];
// The imageView can be zoomed largest size
imageView.frame = CGRectMake(0, 0, MRScreenWidth * 2.5, MRScreenHeight * 2.5);
imageView.userInteractionEnabled = YES;
[self addSubview:imageView];
[imageView release];
// Add gesture,double tap zoom imageView.
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTapGesture setNumberOfTapsRequired:2];
[imageView addGestureRecognizer:doubleTapGesture];
[doubleTapGesture release];
float minimumScale = self.frame.size.width / imageView.frame.size.width;
[self setMinimumZoomScale:minimumScale];
[self setZoomScale:minimumScale];
}
#pragma mark - Zoom methods
- (void)handleDoubleTap:(UIGestureRecognizer *)gesture
{
float newScale = self.zoomScale * 1.5;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gesture locationInView:gesture.view]];
[self zoomToRect:zoomRect animated:YES];
}
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center
{
CGRect zoomRect;
zoomRect.size.height = self.frame.size.height / scale;
zoomRect.size.width = self.frame.size.width / scale;
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
#pragma mark - UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageView;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
[scrollView setZoomScale:scale animated:NO];
}
You can do it by using UIScrollView and enable enabledZoom ON.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
in viewDidLoad method paste this code
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView.minimumZoomScale=0.5;
self.scrollView.maximumZoomScale=6.0;
self.scrollView.contentSize=CGSizeMake(1280, 960);
self.scrollView.delegate=self;
}
Look at this tutorial, it was helpful for me:
Assuming you have a property scrollView, try the following code in your view controller s viewDidLoad or viewWillAppear methods:
self.scrollView.minimumZoomScale=1.0;
self.scrollView.maximumZoomScale=2.0;
self.scrollView.contentSize=self.scrollView.frame.size;
self.scrollView.bounces=YES;
self.scrollView.delegate=self;
Let your view controller conform to the UIScrollViewDelegate protocol. And implement the delegate method :
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;// return the imageView inside the scrollview which has to be scaled.
}

iOS Implicit conversion of 'int' to 'UIColor*' is disallowed with ARC

I have a pickerview that is getting its information from a separate AFPickerView file. I'm getting the error "Implicit conversion of 'int' to 'UIColor*' is disallowed with ARC". Any suggestions on an easy fix for this?
Here is the code that it effects:
[visibleViews minusSet:recycledViews];
// add missing pages
for (int index = firstNeededViewIndex; index <= lastNeededViewIndex; index++)
{
if (![self isDisplayingViewForIndex:index])
{
UILabel *label = (UILabel *)[self dequeueRecycledView];
if (label == nil)
{
label = [[UILabel alloc] initWithFrame:CGRectMake(_rowIndent, 0, self.frame.size.width - _rowIndent, 39.0)];
label.backgroundColor = [UIColor clearColor];
label.font = self.rowFont;
label.textColor = RGBACOLOR(0.0, 0.0, 0.0, 0.75);
}
[self configureView:label atIndex:index];
[contentView addSubview:label];
[visibleViews addObject:label];
}
}
}
Here is the full code:
#import "AFPickerView.h"
#implementation AFPickerView
#pragma mark - Synthesization
#synthesize dataSource;
#synthesize delegate;
#synthesize selectedRow = currentRow;
#synthesize rowFont = _rowFont;
#synthesize rowIndent = _rowIndent;
#pragma mark - Custom getters/setters
- (void)setSelectedRow:(int)selectedRow
{
if (selectedRow >= rowsCount)
return;
currentRow = selectedRow;
[contentView setContentOffset:CGPointMake(0.0, 39.0 * currentRow) animated:NO];
}
- (void)setRowFont:(UIFont *)rowFont
{
_rowFont = rowFont;
for (UILabel *aLabel in visibleViews)
{
aLabel.font = _rowFont;
}
for (UILabel *aLabel in recycledViews)
{
aLabel.font = _rowFont;
}
}
- (void)setRowIndent:(CGFloat)rowIndent
{
_rowIndent = rowIndent;
for (UILabel *aLabel in visibleViews)
{
CGRect frame = aLabel.frame;
frame.origin.x = _rowIndent;
frame.size.width = self.frame.size.width - _rowIndent;
aLabel.frame = frame;
}
for (UILabel *aLabel in recycledViews)
{
CGRect frame = aLabel.frame;
frame.origin.x = _rowIndent;
frame.size.width = self.frame.size.width - _rowIndent;
aLabel.frame = frame;
}
}
#pragma mark - Initialization
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// setup
[self setup];
// backgound
UIImageView *bacground = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"pickerBackground.png"]];
[self addSubview:bacground];
// content
contentView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, frame.size.width, frame.size.height)];
contentView.showsHorizontalScrollIndicator = NO;
contentView.showsVerticalScrollIndicator = NO;
contentView.delegate = self;
[self addSubview:contentView];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(didTap:)];
[contentView addGestureRecognizer:tapRecognizer];
// shadows
UIImageView *shadows = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"pickerShadows.png"]];
[self addSubview:shadows];
// glass
UIImage *glassImage = [UIImage imageNamed:#"pickerGlass.png"];
glassImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 76.0, glassImage.size.width, glassImage.size.height)];
glassImageView.image = glassImage;
[self addSubview:glassImageView];
}
return self;
}
- (void)setup
{
_rowFont = [UIFont boldSystemFontOfSize:24.0];
_rowIndent = 30.0;
currentRow = 0;
rowsCount = 0;
visibleViews = [[NSMutableSet alloc] init];
recycledViews = [[NSMutableSet alloc] init];
}
#pragma mark - Buisness
- (void)reloadData
{
// empry views
currentRow = 0;
rowsCount = 0;
for (UIView *aView in visibleViews)
[aView removeFromSuperview];
for (UIView *aView in recycledViews)
[aView removeFromSuperview];
visibleViews = [[NSMutableSet alloc] init];
recycledViews = [[NSMutableSet alloc] init];
rowsCount = [dataSource numberOfRowsInPickerView:self];
[contentView setContentOffset:CGPointMake(0.0, 0.0) animated:NO];
contentView.contentSize = CGSizeMake(contentView.frame.size.width, 39.0 * rowsCount + 4 * 39.0);
[self tileViews];
}
- (void)determineCurrentRow
{
CGFloat delta = contentView.contentOffset.y;
int position = round(delta / 39.0);
currentRow = position;
[contentView setContentOffset:CGPointMake(0.0, 39.0 * position) animated:YES];
[delegate pickerView:self didSelectRow:currentRow];
}
- (void)didTap:(id)sender
{
UITapGestureRecognizer *tapRecognizer = (UITapGestureRecognizer *)sender;
CGPoint point = [tapRecognizer locationInView:self];
int steps = floor(point.y / 39) - 2;
[self makeSteps:steps];
}
- (void)makeSteps:(int)steps
{
if (steps == 0 || steps > 2 || steps < -2)
return;
[contentView setContentOffset:CGPointMake(0.0, 39.0 * currentRow) animated:NO];
int newRow = currentRow + steps;
if (newRow < 0 || newRow >= rowsCount)
{
if (steps == -2)
[self makeSteps:-1];
else if (steps == 2)
[self makeSteps:1];
return;
}
currentRow = currentRow + steps;
[contentView setContentOffset:CGPointMake(0.0, 39.0 * currentRow) animated:YES];
[delegate pickerView:self didSelectRow:currentRow];
}
#pragma mark - recycle queue
- (UIView *)dequeueRecycledView
{
UIView *aView = [recycledViews anyObject];
if (aView)
[recycledViews removeObject:aView];
return aView;
}
- (BOOL)isDisplayingViewForIndex:(NSUInteger)index
{
BOOL foundPage = NO;
for (UIView *aView in visibleViews)
{
int viewIndex = aView.frame.origin.y / 39.0 - 2;
if (viewIndex == index)
{
foundPage = YES;
break;
}
}
return foundPage;
}
- (void)tileViews
{
// Calculate which pages are visible
CGRect visibleBounds = contentView.bounds;
int firstNeededViewIndex = floorf(CGRectGetMinY(visibleBounds) / 39.0) - 2;
int lastNeededViewIndex = floorf((CGRectGetMaxY(visibleBounds) / 39.0)) - 2;
firstNeededViewIndex = MAX(firstNeededViewIndex, 0);
lastNeededViewIndex = MIN(lastNeededViewIndex, rowsCount - 1);
// Recycle no-longer-visible pages
for (UIView *aView in visibleViews)
{
int viewIndex = aView.frame.origin.y / 39 - 2;
if (viewIndex < firstNeededViewIndex || viewIndex > lastNeededViewIndex)
{
[recycledViews addObject:aView];
[aView removeFromSuperview];
}
}
[visibleViews minusSet:recycledViews];
// add missing pages
for (int index = firstNeededViewIndex; index <= lastNeededViewIndex; index++)
{
if (![self isDisplayingViewForIndex:index])
{
UILabel *label = (UILabel *)[self dequeueRecycledView];
if (label == nil)
{
label = [[UILabel alloc] initWithFrame:CGRectMake(_rowIndent, 0, self.frame.size.width - _rowIndent, 39.0)];
label.backgroundColor = [UIColor clearColor];
label.font = self.rowFont;
label.textColor = RGBACOLOR(0.0, 0.0, 0.0, 0.75);
}
[self configureView:label atIndex:index];
[contentView addSubview:label];
[visibleViews addObject:label];
}
}
}
- (void)configureView:(UIView *)view atIndex:(NSUInteger)index
{
UILabel *label = (UILabel *)view;
label.text = [dataSource pickerView:self titleForRow:index];
CGRect frame = label.frame;
frame.origin.y = 39.0 * index + 78.0;
label.frame = frame;
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self tileViews];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
[self determineCurrentRow];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self determineCurrentRow];
}
#end
This should work with ARC. Replace RGBACOLOR with colorWithRed:green:blue:alpha
label.textColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.75f];

Zoom not working in Custom UIScrollView

I have a problem with a custom class of UIScrollView that I use to hold an UIImageView inside of it.
I have another ViewController with a Main UIScrollView that I add some objects of the CustomScrollViewClass Class. I am trying to enable zooming inside this custom UIScrollvView but with no sucess!!!
Everything seems to work fine BUT I cannot zoom the UIImageView inside my object from CustomScrollViewClass! I have tried a lot of things but nothing worked by now.
//CustomScrollViewClass .h file
#import <UIKit/UIKit.h>
#interface CustomScrollViewClass : UIScrollView <UIScrollViewDelegate>
{
BOOL iPad;
BOOL iPhone5;
NSString *imageName;
UIImageView *imageView;
}
#property (nonatomic,strong) NSString *imageName;
#property (nonatomic,strong) UIImageView *imageView;
- (id)initWithImageAndFrame:(CGRect)frame imageName:(NSString*)image;
#end
This is the .m file
//CustomScrollViewClass .m file
#import "CustomScrollViewClass.h"
#implementation CustomScrollViewClass
#synthesize imageName,imageView;
- (id)initWithImageAndFrame:(CGRect)frame imageName:(NSString*)image
{
self = [super initWithFrame:frame];
if (self) {
CGRect imagef;
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
if (screenSize.height > 480.0f) {
iPhone5 = YES;
imagef = CGRectMake(0, 0, 320, 388);
} else {
iPhone5 = NO;
imagef = CGRectMake(0, 0, 320, 420);
}
iPad = NO;
} else {
iPad = YES;
iPhone5 = NO;
imagef = CGRectMake(0, 0, 768, 824);
}
self.contentSize = imagef.size;
self.maximumZoomScale = 2.0;
self.minimumZoomScale = 1.0;
self.zoomScale = 1.0;
self.userInteractionEnabled = YES;
self.multipleTouchEnabled = YES;
imageName = image;
UIImageView *imageAux = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
imageAux.frame = imagef;
imageAux.contentMode = UIViewContentModeScaleAspectFit;
imageView = imageAux;
[self addSubview:imageView];
NSLog(#"%#",imageName);
}
return self;
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
NSLog(#"%#",#"viewForZoomingInScrollView");
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
NSLog(#"%#",#"scrollViewDidZoom");
}
#end
As you can see it should work with zoom but it does not! The image appears noarmally. The part of the code I use to add custom views of it is this one (in this example I add 5 custom views in the Main UIScrollView):
//Method in MainView that I add objects from CustomScrollViewClass
-(void)PrepareScrollView
{
CGSize scrollviewc;
//Add Main ScrollView
UIScrollView *scroll = [[UIScrollView alloc] init];
if (iPad) {
scrollviewf = CGRectMake(0, 200, 768, 824);
scrollviewc = CGSizeMake((768 * 5), 824);
}
else {
if (iPhone5){
scrollviewf = CGRectMake(0, 180, 320, 388);
scrollviewc = CGSizeMake((320 * 5), 388);
} else {
scrollviewf = CGRectMake(0, 60, 320, 420);
scrollviewc = CGSizeMake((320 * 5), 420);
}
}
scroll.frame = scrollviewf;
scroll.contentSize = scrollviewc;
scroll.pagingEnabled = YES;
for (int i = 0; i < 5; i++) {
CGRect imagef;
if (iPad) {
imagef = CGRectMake((i * 768), 0, 768, 824);
} else {
if (iPhone5){
imagef = CGRectMake((i * 320), 0, 320, 388);
} else {
imagef = CGRectMake((i * 320), 0, 320, 420);
}
}
//Add Custom ScrollView with UIImageView
CustomScrollViewClass *AUX = [[ImageView alloc] initWithImageAndFrame:imagef imageName:[NSString stringWithFormat:#"%i%#",i+1,#"_pt.jpg"]];
[scroll addSubview:AUX];
}
self.scrollView = scroll;
[self.view addSubview:self.scrollView];
}

UIScroll center image

I've edited this question a few times, but can still not get my images to center inside a uiview. I want them to be able to rotate like the photos app and display the correct size when a user brings them up. Here is what I'm working with:
In my PhotoViewController.h
#import <UIKit/UIKit.h>
#protocol PhotoViewControllerDelegate <NSObject>
- (void)toggleChromeDisplay;
#end
#interface PhotoViewController : UIViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate>
#property (nonatomic, strong) UIImage *photo;
#property (nonatomic) NSUInteger num;
//Delegate
#property (nonatomic, strong) id<PhotoViewControllerDelegate> photoViewControllerDelegate;
#property (nonatomic, strong) UIImageView *photoImgView;
#property (nonatomic, strong) UIScrollView *scrollView;
#end
In my PhotoViewController.m:
#import "PhotoViewController.h"
#interface PhotoViewController ()
#end
#implementation PhotoViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//todo
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect screenBounds = self.view.bounds;
//scroll view
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, screenBounds.size.width, screenBounds.size.height)];
_scrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
_scrollView.pagingEnabled = NO;
_scrollView.scrollEnabled = YES;
[_scrollView setBackgroundColor:[UIColor blueColor]];
//Zoom Properties
_scrollView.maximumZoomScale = 6.0;
_scrollView.minimumZoomScale = 1.0;
_scrollView.bouncesZoom = YES;
_scrollView.delegate = self;
_scrollView.zoomScale = 1.0;
_scrollView.contentSize = _photoImgView.bounds.size;
[_scrollView setShowsHorizontalScrollIndicator:NO];
[_scrollView setShowsVerticalScrollIndicator:NO];
[self photoBounds];
[self.view addSubview: _scrollView];
//Add the UIImageView
_photoImgView = [[UIImageView alloc] initWithImage:_photo];
_photoImgView.image = _photo;
_photoImgView.clipsToBounds = YES;
_photoImgView.contentMode = UIViewContentModeScaleAspectFit;
_photoImgView.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin);
[_photoImgView setUserInteractionEnabled:YES];
[_scrollView addSubview: _photoImgView];
//Set up Gesture Recognizer
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
UITapGestureRecognizer *dTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dTapGestureCaptured:)];
dTap.numberOfTapsRequired = 2;
[singleTap requireGestureRecognizerToFail:dTap];
//Gesture Methods
[self.scrollView addGestureRecognizer:singleTap];
[self.scrollView addGestureRecognizer : dTap];
}
- (void)photoBounds
{
UIInterfaceOrientation statusbar = [[UIApplication sharedApplication] statusBarOrientation];
CGSize photoBounds = _photo.size;
CGSize scrollBounds = self.view.bounds.size;
CGRect frameToCenter = [_photoImgView frame];
float newHeight = (scrollBounds.width / photoBounds.width) * photoBounds.height;
float newWidth = (scrollBounds.height / photoBounds.height) * photoBounds.width;
float yDist = fabsf(scrollBounds.height - newHeight) / 2;
float xDist = fabsf(scrollBounds.width - newWidth) / 2;
//Width Larger
if (photoBounds.width >=photoBounds.height) {
NSLog(#"portrait width");
_photoImgView.frame = CGRectMake(0, 0, scrollBounds.width, newHeight);
frameToCenter.origin.y = yDist;
}
//Height Larger
else if (photoBounds.height > photoBounds.width) {
NSLog(#"portrait height");
_photoImgView.frame = CGRectMake(0, 0, newWidth, scrollBounds.height);
frameToCenter.origin.x = xDist;
}
//Square
else {
NSLog(#"portrait square");
if ((statusbar == 1) || (statusbar == 2)) {
_photoImgView.frame = CGRectMake(0, 0, scrollBounds.width, newHeight);
frameToCenter.origin.y = yDist;
} else {
_photoImgView.frame = CGRectMake(0, 0, newWidth, scrollBounds.height);
frameToCenter.origin.x = xDist;
}
}
}
//Rotation Magic
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//later
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self photoBounds];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
//
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
//Zoom Ability
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.photoImgView;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
NSLog(#"scale %f", scale);
NSLog(#"done zooming");
}
//Touches Control
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
//CGPoint touchPoint=[gesture locationInView:_scrollView];
NSLog(#"touched");
NSLog(#"single touch");
[self performSelector:#selector(callingHome) withObject:nil afterDelay:0];
}
- (void)dTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
NSLog(#"double touched");
}
- (void)panGestureCaptured:(UIPanGestureRecognizer *)gesture
{
NSLog(#"pan gesture");
}
- (void)callingHome {}
#end
The overall issue is that I can not get my picture to display correctly and be able to zoom on just it, no space around it and It needs to be the correct dimensions on load. I've been struggling with it for a few days.
Any help?
I have resolved a similar problem using a really simple subclass of UIScrollView of my own. You can take a look at it here - https://gist.github.com/ShadeApps/5a29e1cea3e1dc3df8c8. Works like charm for me.
That's how you init it:
scrollViewMain.delegate = self;
scrollViewMain.minimumZoomScale = 1.0;
scrollViewMain.maximumZoomScale = 3.0;
scrollViewMain.contentSize = imageViewMain.frame.size;
scrollViewMain.backgroundColor = [UIColor blackColor];
scrollViewMain.tileContainerView = imageViewMain;
There is awesome blog post about this problem from Peter Steinberger: http://petersteinberger.com/blog/2013/how-to-center-uiscrollview/

Resources