When the user pans their finger over the specific cell, the cell changes color depending on the x-axis of the user. How would I go about changing from a pan gesture to a swipe. I would like to build it so that instead of panning, swiping on the cell reveals the color behind it. The cell should then snap back into place when the user lifts their finger. Any tips?
#synthesize _panRecognizer;
- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier])
{
NSInteger emoteY = floor((self.frame.size.height - 32) / 2);
_panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(respondToPanGesture:)];
[_panRecognizer setDelegate:self];
[_panRecognizer setMinimumNumberOfTouches:1];
[_panRecognizer setMaximumNumberOfTouches:1];
[self addGestureRecognizer:_panRecognizer];
// [[self textLabel] setFont:[UIFont boldSystemFontOfSize:18.0]];
[[self textLabel] setFont:[UIFont systemFontOfSize:24.0]];
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
_border = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, self.frame.size.height)];
[self addSubview:_border];
_rightEmote = [[UIImageView alloc] initWithFrame:CGRectMake(self.frame.size.width - 42, emoteY, 32, 32)];
[self addSubview:_rightEmote];
_leftEmote = [[UIImageView alloc] initWithFrame:CGRectMake(-32, emoteY, 32, 32)];
[self addSubview:_leftEmote];
}
return self;
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
CGRect borderFrame = _border.frame,
rightEmoteFrame = _rightEmote.frame,
leftEmoteFrame = _leftEmote.frame;
NSInteger emoteY = floor((self.frame.size.height - 32) / 2);
borderFrame.size.height = self.frame.size.height;
rightEmoteFrame.origin.y = emoteY;
leftEmoteFrame.origin.y = emoteY;
[_border setFrame:borderFrame];
[_rightEmote setFrame:rightEmoteFrame];
[_leftEmote setFrame:leftEmoteFrame];
}
- (DDFactor *)factor
{
return _factor;
}
- (void)setFactor:(DDFactor *)factor
{
_factor = factor;
}
- (void)respondToPanGesture:(UIGestureRecognizer *)recognizer
{
// NSLog(#"%lu", [recognizer state]);
NSInteger rstate = [recognizer state];
CGFloat touchX = 0.0;
if ([recognizer numberOfTouches] == 1)
{
touchX = [recognizer locationOfTouch:0 inView:self].x;
if (rstate == UIGestureRecognizerStateBegan)
{
/*
animate to color under touch
*/
CGRect labelFrame = [self textLabel].frame;
labelFrame.origin.x += 42;
CGRect rightEmoteFrame = _rightEmote.frame;
rightEmoteFrame.origin.x += 42;
CGRect leftEmoteFrame = _leftEmote.frame;
leftEmoteFrame.origin.x += 42;
[UIView animateWithDuration:0.3 animations:^{
[_border setAlpha:0.0];
[[self textLabel] setTextColor:[UIColor whiteColor]];
[[self textLabel] setFrame:labelFrame];
[_rightEmote setFrame:rightEmoteFrame];
[_leftEmote setFrame:leftEmoteFrame];
}];
[self animateEmoticonsWithColor:NO duration:0.3];
}
else if (rstate == UIGestureRecognizerStateChanged)
{
/*
alter color
trigger emote animation if necessary
*/
if ([self responseForTouchPosition:touchX] != _responseValue)
{
[self setResponseValue:[self responseForTouchPosition:touchX]];
[_border setBackgroundColor:[UIColor colorForResponse:_responseValue]];
[self animateToBackgroundColor:[UIColor colorForResponse:_responseValue]];
[self animateEmoticonsWithColor:NO duration:0.2];
}
}
}
else if (([recognizer numberOfTouches] == 0) && (rstate == 3))
{
CGRect labelFrame = [self textLabel].frame;
labelFrame.origin.x -= 42;
CGRect rightEmoteFrame = _rightEmote.frame;
rightEmoteFrame.origin.x -= 42;
CGRect leftEmoteFrame = _leftEmote.frame;
leftEmoteFrame.origin.x -= 42;
[UIView animateWithDuration:0.3 animations:^{
[_border setAlpha:1.0];
[_rightEmote setFrame:rightEmoteFrame];
[_leftEmote setFrame:leftEmoteFrame];
[[self textLabel] setFrame:labelFrame];
[[self textLabel] setTextColor:[UIColor colorForResponse:_responseValue]];
[self setBackgroundColor:[[UIColor colorForResponse:_responseValue] colorWithAlphaComponent:0.1]];
}];
[self animateEmoticonsWithColor:YES duration:0.3];
}
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (DDResponseValue)responseForTouchPosition:(CGFloat)x
{
DDResponseValue response;
if (x <= 70) response = DDResponseGrin;
else if (x <= 120) response = DDResponseSmile;
else if (x <= 170) response = DDResponseSad;
else if (x <= 220) response = DDResponseNervous;
else if (x <= 270) response = DDResponseRefusal;
else response = DDResponseNeutral;
return response;
}
You can use the UISwipeGestureRecognizer state and can do as what you want. Have a look on the following code,
- (void)swipeGestureMethod:(UISwipeGestureRecognizer *)recognizer {
CGPoint point = [recognizer locationInView:[recognizer view]];
if (recognizer.state == UIGestureRecognizerStateBegan) {
} else if (recognizer.state == UIGestureRecognizerStateEnded) {
}
}
Related
I'm trying to update frames for two labels during UIPanGesture recognition of a UIView (centre grey color).
Functionality
I need to choose a language between English and Arabic. There is a slider button in middle (grey view) and I have applied UIPanGesture to that. So while swiping towards Arabic the language English should move to centre and assumes that its selected and vice versa.
I tried my level best but I can only make upto this. Frames are not setting properly and I don't know is there any other easy way to do this.
Code
- (void)viewDidLoad {
[super viewDidLoad];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[dragview addGestureRecognizer:gesture];
}
- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
CGPoint velocity = [gestureRecognizer velocityInView: gestureRecognizer.view];
CGPoint location = [gestureRecognizer locationInView: gestureRecognizer.view];
if(velocity.x > 0)
{
NSLog(#"gesture went right");
if (dragview.frame.origin.x + dragview.frame.size.width >= dragV.frame.size.width) {
[dragview setFrame:CGRectMake(dragV.frame.size.width - dragview.frame.size.width, dragview.frame.origin.y, dragview.frame.size.width, dragview.frame.size.height)];
english.center = CGPointMake(dragV.frame.size.width / 2,
dragV.frame.size.height / 2);
} else {
float dX = location.x-panCoord.x;
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x+dX, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
[english setFrame:CGRectMake(english.frame.origin.x + 1.0f, english.frame.origin.y, english.frame.size.width, english.frame.size.height)];
[arabic setFrame:CGRectMake(arabic.frame.origin.x + 1.0f, arabic.frame.origin.y, arabic.frame.size.width, arabic.frame.size.height)];
}
}
else
{
NSLog(#"gesture went left");
if (dragview.frame.origin.x <= 0) {
[dragview setFrame:CGRectMake(0, dragview.frame.origin.y, dragview.frame.size.width, dragview.frame.size.height)];
arabic.center = CGPointMake(dragV.frame.size.width / 2,
dragV.frame.size.height / 2);
} else {
float dX = location.x+panCoord.x;
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x+dX, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
[english setFrame:CGRectMake(english.frame.origin.x - 1.0f, english.frame.origin.y, english.frame.size.width, english.frame.size.height)];
[arabic setFrame:CGRectMake(arabic.frame.origin.x - 1.0f, arabic.frame.origin.y, arabic.frame.size.width, arabic.frame.size.height)];
}
}
}
Screenshots
Initially it looks like this,
While dragging towards arabic,
While dragging towards english,
Answers are appreciated!!
I got output.I tried your code and I used SwipeGestureRecognizer code.It works fine now.
I tried with 2 optins
OPTION 1:SwipeGestureRecognizer
- (void)viewDidLoad
{
[super viewDidLoad];
// Swipe Left
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeLeft:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[arabicView addGestureRecognizer:swipeLeft];
// Swipe Right
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeRight:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[englishView addGestureRecognizer:swipeRight];
}
- (void)handleSwipeLeft:(UISwipeGestureRecognizer *)recognizer
{
[self performSelector:#selector(moveAtRight) withObject:nil afterDelay:0.01f];
}
- (void)handleSwipeRight:(UISwipeGestureRecognizer *)recognizer
{
[self performSelector:#selector(moveAtLeft) withObject:nil afterDelay:0.01f];
}
-(void)moveAtRight
{
englishView.frame = CGRectMake(0, 0, 53, 53);
englishView.backgroundColor = [UIColor lightGrayColor];
arabicView.frame = CGRectMake(53, 0, 205, 53);
english.text = #"English";
arabic.text = #"Arabic";
arabicView.backgroundColor = [UIColor blueColor];
[dragview removeFromSuperview];
}
-(void)moveAtLeft
{
englishView.frame = CGRectMake(0, 0, 205, 53);
arabicView.frame = CGRectMake(205, 0, 53, 53);
arabicView.backgroundColor = [UIColor lightGrayColor];
englishView.backgroundColor = [UIColor blueColor];
english.text = #"English";
arabic.text = #"Arabic";
[dragview removeFromSuperview];
}
In above code I set background color to blue.If you want to any other color change.
At Initial
When I swipe towards Arabic
When I swipe towards English
Above these are output.
OPTION 2:PanGestureRecognizer
Now I tried with your PanGestureRecognizer Code.I set frame and background color for englishView and arabicView separately.Now it works fine.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_drawPath = [UIBezierPath
bezierPathWithRoundedRect:CGRectMake(0, 0, 140, 35)
byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight | UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(4, 4)
];
_rectLayer = [[CAShapeLayer alloc] init];
_rectLayer.path = _drawPath.CGPath;
_rectLayer.strokeColor = [UIColor blackColor].CGColor;
_rectLayer.lineWidth = 2.0f;
_rectLayer.fillColor = [UIColor clearColor].CGColor;
_rectLayer.strokeEnd = 0.f;
[vi.layer addSublayer:_rectLayer];
[self drawRectangle:nil];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[gesture setMinimumNumberOfTouches:1];
[gesture setMaximumNumberOfTouches:1];
[englishView addGestureRecognizer:gesture];
UIPanGestureRecognizer *gesture1 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[gesture1 setMinimumNumberOfTouches:1];
[gesture1 setMaximumNumberOfTouches:1];
[arabicView addGestureRecognizer:gesture1];
}
- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateChanged)
{
NSLog(#"Changed");
CGPoint velocity = [gestureRecognizer velocityInView:gestureRecognizer.view];
CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view];
if(velocity.x > 0)
{
NSLog(#"gesture went right");
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x + translation.x, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
NSLog(#"The gestureRecognizer frame is - %#",NSStringFromCGRect(gestureRecognizer.view.frame));
[englishView setFrame:CGRectMake(0, englishView.frame.origin.y, 205, englishView.frame.size.height)];
[englishView setBackgroundColor:[UIColor colorWithRed:(15/255.0f) green:(97/255.0f) blue:(163/255.0f) alpha:1.0f]];
[arabicView setFrame:CGRectMake(205, arabicView.frame.origin.y, 53, arabicView.frame.size.height)];
[arabicView setBackgroundColor:[UIColor lightGrayColor]];
[gestureRecognizer setTranslation:CGPointMake(0, 0) inView:dragV];
[dragview removeFromSuperview];
}
else
{
NSLog(#"gesture went left");
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x + translation.x, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
[arabicView setFrame:CGRectMake(53, arabicView.frame.origin.y, 205, arabicView.frame.size.height)];
[englishView setFrame:CGRectMake(0, englishView.frame.origin.y,53,englishView.frame.size.height)];
[arabicView setBackgroundColor:[UIColor colorWithRed:(15/255.0f) green:(97/255.0f) blue:(163/255.0f) alpha:1.0f]];
[englishView setBackgroundColor:[UIColor lightGrayColor]];
[gestureRecognizer setTranslation:CGPointMake(0, 0) inView:dragV];
[dragview removeFromSuperview];
}
}
}
At First once I run the app
Middle Finger towards Arabic View
Middle Finger towards English View
In my application having gallery functionality.For Scrolling image i used REPagedScrollView and i want to image zoom on pinch using 2 finger and also want zoom on double tap but i unable to to zoom image on double tap
please resolved my problem.
I tried by below code :
.h file
#interface ViewPhotoVC : UIViewController<UIScrollViewDelegate,UIGestureRecognizerDelegate>
{
REPagedScrollView *scrollView;
UIScrollView *image_scroll;
int current_page;
BOOL is_FullScreen;
}
#property (strong,nonatomic) IBOutlet UIView *slider_view;
.m file
-(void)video_image_Gallery
{
scrollView = [[REPagedScrollView alloc] initWithFrame:self.slider_view.bounds];
scrollView.delegate=self;
// scrollView.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
// scrollView.pageControl.currentPageIndicatorTintColor = [UIColor grayColor];
current_page=0;
for(int i=0;i<[self.PhotoImgArr count];i++){
self.image_view = [[AsyncImageView alloc] initWithFrame:CGRectMake(0,0, self.slider_view.frame.size.width, self.slider_view.frame.size.height)];
// scrollView.frame=CGRectMake(0, 0, screenwidth, screenheight);
image_scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,screenwidth,screenheight)];
self.image_view.backgroundColor=[UIColor clearColor];
self.image_view.contentMode = UIViewContentModeScaleAspectFit;
self.image_view.clipsToBounds = true;
self.image_view.userInteractionEnabled = YES;
self.image_view.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin);
self.image_view.image = [UIImage imageNamed:#"no_image1.png"];
self.image_view.imageURL =[NSURL URLWithString:[self.PhotoImgArr objectAtIndex:i]];
self.image_view.backgroundColor = [UIColor colorWithRed:247.0/255.0 green:246.0/255.0 blue:241.0/255.0 alpha:1];
[image_scroll setDelegate:self];
[image_scroll setShowsHorizontalScrollIndicator:NO];
[image_scroll setShowsVerticalScrollIndicator:NO];
[image_scroll setMaximumZoomScale:8.0];
image_scroll.tag=i+1;
self.PlayVideoBtn.tag=i+1;
self.image_view.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
image_scroll.contentSize = CGSizeMake(self.image_view.bounds.size.width-500, self.image_view.bounds.size.height-300);
image_scroll.decelerationRate = UIScrollViewDecelerationRateFast;
// [image_scroll setMinimumZoomScale:[image_scroll frame].size.width / [self.image_view frame].size.width];
[image_scroll setZoomScale:[image_scroll minimumZoomScale]];
[image_scroll addSubview:self.image_view];
[image_scroll addSubview:self.PlayVideoBtn];
[image_scroll addSubview:self.videoImg];
scrollView.tag=0;
// self.PlayVideoBtn.tag=0;
[scrollView addPage:image_scroll];
}
[self.slider_view addSubview:scrollView];
self.index_lbl.text = [NSString stringWithFormat:#"%d of %lu",(int)self.selected_index+1,(unsigned long)[self.PhotoImgArr count]];
[scrollView scrollToPageWithIndex:self.selected_index animated:YES];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView1
{
if(scrollView1.tag ==0){
CGFloat pageWidth = scrollView1.frame.size.width;
current_page = floor((scrollView1.contentOffset.x - pageWidth / 2.0) / pageWidth) + 1;
self.index_lbl.text = [NSString stringWithFormat:#"%d of %lu",current_page+1,(unsigned long)[self.PhotoImgArr count]];
if(current_page+1==self.PhotoImgArr.count)
{
self.nextBtn.userInteractionEnabled=NO;
self.nextImg.image=[UIImage imageNamed:#"disable_next.png"];
}
else if(current_page==0)
{
self.prevBtn.userInteractionEnabled=NO;
self.prevImg.image=[UIImage imageNamed:#"disable_prev.png"];
}
else
{
self.nextBtn.userInteractionEnabled=YES;
self.prevBtn.userInteractionEnabled=YES;
self.nextImg.image=[UIImage imageNamed:#"next.png"];
self.prevImg.image=[UIImage imageNamed:#"prev.png"];
}
}
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView1 {
if([self.PhotoOrVideo isEqualToString:#"Photo"])
{
if([[scrollView1 viewWithTag:scrollView1.tag].subviews count]>0){
return [[scrollView1 viewWithTag:scrollView1.tag].subviews objectAtIndex:0];
}
}
return nil;
}
Please try the below code:
-(void)setScrollView:(UIScrollView *)scrollView
{
_scrollView=scrollView;
_scrollView.minimumZoomScale=0.2;
_scrollView.maximumZoomScale=3.0;
_scrollView.delegate=self;
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
[self.scrollView flashScrollIndicators];
}
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];
This is written in my UICollectionViewCell but pinch never get called.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self.contentView setBackgroundColor:[UIColor clearColor]];
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0.0, 0.0, frame.size.width,frame.size.height)];
UIPinchGestureRecognizer *pgr = [[UIPinchGestureRecognizer alloc]
initWithTarget:self action:#selector(pinch:)];
[self.imageView addGestureRecognizer:pgr];
[self.contentView addSubview:imageView];
imageView.contentMode=UIViewContentModeScaleAspectFill;
[imageView setClipsToBounds:TRUE];
_imageView = imageView;
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityIndicator.center = _imageView.center;
activityIndicator.hidesWhenStopped = YES;
[_imageView addSubview:activityIndicator];
_activityIndicator=activityIndicator;
self.imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
}
return self;
}
- (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 < 1.0) {
newScale = 1.0;
}
if (newScale > 4.0) {
newScale = 4.0;
}
CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale);
self.transform = transform;
gesture.scale = 1;
}
}
Not sure weather I am correct but from your code below :
[self.imageView addGestureRecognizer:pgr];
[self.contentView addSubview:imageView];
you are trying to add the gesture on an iVar but adding a local variable to self.contentView.
You please set the UserInteractionsenable to YES for your imageView,because by default it is set to NO for that.then it will work fine.
I have two Scroll View's in a xib, and they both contain a very large image that should start with it completely scaled down to fit. The first ScrollView works perfectly, objects are all moving around correctly when you zoom or scroll, but the second ScrollView starts completely zoomed in, unable to zoom out.
The ScrollView is now showing 25% of the image(completely zoomed in at 0,0) and also cannot be dragged to see the rest. If I pinch to zoom, the image moves diagonally up and left without zooming at all, I can now drag the image back to 0,0 and back down the the max point it scrolled diagonally.
.h file
UIScrollView *_scrollView;
UIScrollView *_miamiScrollView;
UIView *_mapImageView;
UIView *_mapMiamiView;
UIView *_mapContentView;
NSArray *_autoLayoutViews;
NSArray *_staticViews;
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;//(linked to working scrollview)
#property (strong, nonatomic) IBOutlet UIScrollView *miamiScrollView;//(Linked to 'broken' scrollview)
.m file
- (void)viewDidLoad
{
[self _customizeViews];
}
- (void) _customizeViews
{
UIImageView *mapImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"MainGameDisplay.jpg"]];
mapImageView.userInteractionEnabled = YES;
UIImageView *mapMiamiView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"miami.jpg"]];
mapMiamiView.userInteractionEnabled = YES;
_mapContentView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, 568, 270)];
_mapContentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
_mapContentView.clipsToBounds = YES;
_mapContentView.userInteractionEnabled = YES;
[_mapContentView addSubview:_scrollView];
[_mapContentView addSubview:_miamiScrollView];
[self.view addSubview:_mapContentView];
[self.view sendSubviewToBack:_mapContentView];
UIScrollView *scrollView = _scrollView;
CGRect scrollFrame = scrollView.frame;
scrollFrame.origin = CGPointZero;
scrollView.frame = scrollFrame;
scrollView.delegate = self;
scrollView.minimumZoomScale = 1;
scrollView.maximumZoomScale = 1.0;
[scrollView addSubview:mapImageView];
scrollView.contentSize = mapImageView.frame.size;
_scrollView = scrollView;
_mapImageView = mapImageView;
UIScrollView *miamiScrollView = _miamiScrollView;
CGRect miamiScrollFrame = CGRectMake(0 , 270, 568, 270);
scrollFrame.origin = CGPointZero;
miamiScrollView.frame = miamiScrollFrame;
miamiScrollView.delegate = self;
miamiScrollView.minimumZoomScale = 0.125;
miamiScrollView.maximumZoomScale = 1;
[miamiScrollView addSubview:mapMiamiView];
miamiScrollView.contentSize = mapMiamiView.frame.size;
_miamiScrollView = miamiScrollView;
_mapMiamiView = mapMiamiView;
[self _setupAutolayoutViews];
[self _setupStaticViews];
[self _zoomToFit: _scrollView];
[self _zoomToFit: _miamiScrollView];
[self _updatePositionForViews:_autoLayoutViews];
}
- (void) _zoomToFit: (UIScrollView*)view
{
CGFloat contentWidth = view.contentSize.width;
CGFloat contentHeigth = view.contentSize.height;
CGFloat viewWidth = view.frame.size.width;
CGFloat viewHeight = view.frame.size.height;
CGFloat width = viewWidth / contentWidth;
CGFloat heigth = viewHeight / contentHeigth;
CGFloat scale = MAX(width, heigth);
if ( scale < view.minimumZoomScale ) {
view.minimumZoomScale = scale;
} else if ( scale > view.maximumZoomScale ) {
view.maximumZoomScale = scale;
}
view.zoomScale = scale;
}
#pragma mark - Positions
- (void) _updatePositionForViews:(NSArray *)views
{
CGFloat scale = _scrollView.zoomScale;
CGPoint contentOffset = _scrollView.contentOffset;
contentOffset.x -= _scrollView.frame.origin.x;
contentOffset.y -= _scrollView.frame.origin.y;
for ( UIView *view in views ) {
CGPoint basePosition = [self _basePositionForView:view];
[self _updatePositionForView:view scale:scale basePosition:basePosition offset:contentOffset];
}
}
- (CGPoint) _basePositionForView:(UIView *)view
{
NSString *key = [NSString stringWithFormat:#"%d", view.tag];
NSString *stringValue = [_coordinates objectForKey:key];
NSArray *values = [stringValue componentsSeparatedByString:#":"];
if ( [values count] < 2 ) return CGPointZero;
CGPoint result = CGPointMake([[values objectAtIndex:0] floatValue], [[values objectAtIndex:1] floatValue]);
return result;
}
- (void) _updatePositionForView:(UIView *)view scale:(CGFloat)scale basePosition:(CGPoint)basePosition offset:(CGPoint)offset;
{
CGPoint position;
position.x = (basePosition.x * scale) - offset.x;
position.y = (basePosition.y * scale) - offset.y;
CGRect frame = view.frame;
frame.origin = position;
view.frame = frame;
}
//////////////////////////////////////////////////////////////////////////////////////
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
{
[self _lockInteraction];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{
[self _unlockInteraction];
}
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
[self _lockInteraction];
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;
{
[self _unlockInteraction];
}
- (void) _lockInteraction
{
[self _setControls:_staticViews interacted:NO];
[self _setControls:_autoLayoutViews interacted:NO];
}
- (void) _unlockInteraction
{
[self _setControls:_staticViews interacted:YES];
[self _setControls:_autoLayoutViews interacted:YES];
}
- (void) _setControls:(NSArray *)controls interacted:(BOOL)interacted
{
for ( UIControl *control in controls ) {
if ( [control isKindOfClass:[UIControl class]]) {
control.userInteractionEnabled = interacted;
}
}
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
[self _updatePositionForViews:_autoLayoutViews];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self _updatePositionForViews:_autoLayoutViews];
}
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView;
{
return _mapImageView;
}
//DEFAULT BUTTONS.
- (void) _setupAutolayoutViews
{
UIButton *btn1 = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
[btn1 addTarget:self action:#selector(quickTest:) forControlEvents:UIControlEventTouchUpInside];
btn1.tag = kAddContactButton;
btn1.center = CGPointZero;
[_mapContentView addSubview:btn1];
_autoLayoutViews = [[NSArray alloc] initWithObjects:btn1, nil];
}
//CUSTOM BUTTONS.
- (void) _setupStaticViews
{
UIButton *openMiamiButton = [UIButton buttonWithType:UIButtonTypeCustom];
[openMiamiButton setBackgroundImage:[UIImage imageNamed:#"logo.png"] forState:UIControlStateNormal];
[openMiamiButton addTarget:self action:#selector(quickTest:) forControlEvents:UIControlEventTouchUpInside];
openMiamiButton.frame = CGRectMake(0.0 ,0.0, 50.0, 50.0);
openMiamiButton.tag = OpenMiamiButton;
openMiamiButton.enabled = YES;
openMiamiButton.alpha = 0.5;
[_mapImageView addSubview:openMiamiButton];
_staticViews = #[openMiamiButton,];
for ( UIView *view in _staticViews ) {
CGPoint point = [self _basePositionForView:view];
CGRect frame = view.frame;
frame.origin = point;
view.frame = frame;
}
}
//And for the transition between views:
-(void) quickTest: (UIButton *)button
{
/*
if (!openMiami)
openMiami = [[MiamiGameDisplay alloc] initWithNibName:nil bundle:nil];
openMiami.mainPage = self;
[self.navigationController pushViewController:openMiami animated:YES];
*/
if (!testBool){
[UIView animateWithDuration:0.5f
animations:^{
_scrollView.frame = CGRectMake(0 , -270, 568, 270);
}
completion:Nil];
[UIView animateWithDuration:0.5f
animations:^{
_miamiScrollView.frame = CGRectMake(0 , 0, 568, 270);
}
completion:Nil];
testBool=YES;
}
else {
[UIView animateWithDuration:0.5f
animations:^{
_miamiScrollView.frame = CGRectMake(0 , 270, 568, 270);
}
completion:Nil];
[UIView animateWithDuration:0.5f
animations:^{
_scrollView.frame = CGRectMake(0 , 0, 568, 270);
}
completion:Nil];
testBool=NO;
}
}
I've run into a similar issue with scrollViews. Basically, as far as I can tell, only the last scrollView added to the window will respond as a scrollView.
You can produce the same effect with any other type of object being added to the window before the scrollView.
Example :
[[self window] addSubview:logo];
[[self window] addSubview:scrollView];
Will work, but:
[[self window] addSubview:scrollView];
[[self window] addSubview:logo];
will not. (Currently running against iOS 6.1.2 and xCode 4.6.1)