Reset nested uiscrollview zooms when scroll ends - uiscrollview

Nested uiscrolls in a larger uiscroll need to, when zoomed, reset zoom level when they are off screen. I am trying to reset all of them when the scrolling ends but no luck. Any ideas?
myScrollview = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
myScrollview.pagingEnabled = YES;
myScrollview.scrollEnabled =YES;
myScrollview.clipsToBounds = NO;
myScrollview.indicatorStyle = UIScrollViewIndicatorStyleWhite;
myScrollview.showsHorizontalScrollIndicator = YES;
myScrollview.backgroundColor = [UIColor blackColor];
myScrollview.delegate = self;
NSInteger viewcount=4;
NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:#"01.png"],[UIImage imageNamed:#"02.png"],[UIImage imageNamed:#"03.png"],[UIImage imageNamed:#"04.png"],nil];
for (int i = 0; i <viewcount; i++)
{
CGFloat x = i * self.view.frame.size.width;
subView = [[UIScrollView alloc]initWithFrame:CGRectMake(x, 0, self.view.frame.size.width, self.view.frame.size.height)];
[subView setBackgroundColor:[UIColor blackColor]];
[subView setCanCancelContentTouches:NO];
subView.clipsToBounds = NO; // default is NO, we want to restrict drawing within our scrollview
subView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
aImageView = [[UIImageView alloc ] initWithImage:[images objectAtIndex:i]];
[self.aImageView setTag:viewcount];
[subView addSubview:aImageView];
[subView setContentSize:CGSizeMake(aImageView.frame.size.width, subView.frame.size.height)];
subView.minimumZoomScale = 1;
subView.maximumZoomScale = 3;
subView.delegate = self;
[subView setScrollEnabled:YES];
subView.contentSize = aImageView.frame.size;
[myScrollview addSubview:subView];
}
myScrollview.contentSize = CGSizeMake(self.view.frame.size.width*viewcount,self.view.frame.size.height);
[self.view addSubview:myScrollview];
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
NSLog (#"test");
UIView * view = nil;
view = [subView viewWithTag:0];
//return view;
return [scrollView.subviews objectAtIndex:0];
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(#"Did scroll");
[self resetImageZoom];
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
= NSLog(#"Did end decal");
[self resetImageZoom];
}
-(void)resetImageZoom {
NSLog(#"Resetting any image zoom");
for(UIView *view in [myScrollview subviews]) {
//if([view isKindOfClass:[UIScrollView class]]) {
//[(UIScrollView*)view setZoomScale:1.0 animated:NO];
//}
view.transform = CGAffineTransformIdentity;
}
}

That did it...
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
NSLog(#"Did end dece");
for (UIView *view in scrollView.subviews) {
if([view isKindOfClass:[UIScrollView class]]) {
[(UIScrollView*)view setZoomScale:1.0 animated:NO];
}
}
}

Related

How to delete UITextfield on tap?

I have a program that when I tap the view a UITextField will appear. I also have an Undo-Button. I wanted to make a delete function when I double tap the UITextfield it can be deleted. Please Help Me.
Here is my code:
ViewController.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface ViewController : UIViewController<UITextFieldDelegate, UIGestureRecognizerDelegate>
{
NSMutableArray *textfieldform;
UITextField *textField1;
float angle;
CGFloat beginX;
CGFloat beginY;
IBOutlet UIView *blahBlah;
CGPoint prevPanPoint;
float prevPinchScale;
float prevRotation;
}
#property (nonatomic, retain) NSMutableArray *textfieldform;
-(IBAction) undo;
- (IBAction)handleTap2:(UITapGestureRecognizer *)recognizer;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize text1, textfieldform;
- (void)viewDidLoad
{
[super viewDidLoad];
//textfieldform = [[NSMutableArray alloc] init];
// Do any additional setup after loading the view, typically from a nib.
textfieldform = [NSMutableArray arrayWithCapacity:0];
angle = 180;
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scaleImage:)];
[blahBlah addGestureRecognizer:pinchGesture];
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotateImage:)];
[blahBlah addGestureRecognizer:rotationGesture];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panGestureAction:)];
[pan setMaximumNumberOfTouches:1];
[pan setMinimumNumberOfTouches:1];
[blahBlah addGestureRecognizer:rotationGesture];
UITapGestureRecognizer *twoFingersTwoTaps =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(twoFingersTwoTaps)] ];
[twoFingersTwoTaps setNumberOfTapsRequired:2];
[twoFingersTwoTaps setNumberOfTouchesRequired:2];
[blahBlah addGestureRecognizer:twoFingersTwoTaps];
}
- (void)twoFingersTwoTaps {
NSLog(#"Action: Delete text, two taps");
}
-(void)panGestureAction:(UIPanGestureRecognizer *)pan {
if (pan.state == UIGestureRecognizerStateBegan){
prevPanPoint = [pan locationInView:blahBlah];
}
CGPoint curr = [pan locationInView:blahBlah];
float diffx = curr.x - prevPanPoint.x;
float diffy = curr.y - prevPanPoint.y;
CGPoint centre = textField1.center;
centre.x += diffx;
centre.y += diffy;
textField1.center = centre;
prevPanPoint = curr;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if([touch.view isKindOfClass:[UIView class]]) {
return YES;
}
return NO;
}
- (void)scaleImage:(UIPinchGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateBegan)
prevPinchScale = 1.0;
float thisScale = 1 + (recognizer.scale-prevPinchScale);
prevPinchScale = recognizer.scale;
textField1.transform = CGAffineTransformScale(textField1.transform, thisScale, thisScale);
}
- (void)rotateImage:(UIRotationGestureRecognizer *)recognizer
{
if([recognizer state] == UIGestureRecognizerStateEnded) {
prevRotation = 0.0;
}
float thisRotate = recognizer.rotation - prevRotation;
prevRotation = recognizer.rotation;
textField1.transform = CGAffineTransformRotate(textField1.transform, thisRotate);
}
-(IBAction)undo{
UITextField *textFieldToRemove = [textfieldform lastObject];
if (textFieldToRemove) {
[textfieldform removeObject:textFieldToRemove];
[textFieldToRemove removeFromSuperview];
}
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
NSLog(#"textFieldShouldBeginEditing");
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
NSLog(#"textFieldDidBeginEditing");
[textField1 setBackgroundColor:[UIColor colorWithRed:(248/255.0) green:(248/255.0) blue:(255/255.0) alpha:1.0]];
textField1.borderStyle = UITextBorderStyleRoundedRect;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
NSLog(#"textFieldShouldEndEditing");
textField.backgroundColor = [UIColor clearColor];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
NSLog(#"textFieldDidEndEditing");
[textField1 setBackgroundColor:[UIColor clearColor]];
textField1.borderStyle = UITextBorderStyleNone;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSLog(#"textField:shouldChangeCharactersInRange:replacementString:");
if ([string isEqualToString:#"#"]) {
return NO;
}
else {
return YES;
}
}
- (BOOL)textFieldShouldClear:(UITextField *)textField{
NSLog(#"textFieldShouldClear:");
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(#"textFieldShouldReturn:");
if (textField.tag == textfieldform.count) {
textField1 = (UITextField *)[self.view viewWithTag:textfieldform.count];
[textField1 becomeFirstResponder];
}
else {
[textField resignFirstResponder];
}
return YES;
}
- (IBAction)handleTap2:(UITapGestureRecognizer *)recognizer{
if (recognizer.state == UIGestureRecognizerStateEnded){
CGPoint point = [recognizer locationInView:[self view]];
textField1 = [[UITextField alloc] init];
textField1.borderStyle = UITextBorderStyleLine;
textField1.font = [UIFont systemFontOfSize:15];
CGRect frame ;
frame.origin.x = point.x;
frame.origin.y = point.y;
frame.size.width=300;
frame.size.height=40;
textField1.frame=frame;
textField1.autocorrectionType = UITextAutocorrectionTypeNo;
textField1.keyboardType = UIKeyboardTypeDefault;
textField1.returnKeyType = UIReturnKeyDefault;
textField1.clearButtonMode = UITextFieldViewModeWhileEditing;
textField1.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField1.delegate = self;
textField1.tag = textfieldform.count;
textField1.font = [UIFont fontWithName:#"Arial" size:30];
[textfieldform addObject:textField1];
[blahBlah addSubview:textField1];
[textField1 addTarget:self action:#selector(wasDragged:withEvent:) forControlEvents:UIControlEventTouchDragInside];
}
}
- (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event{
// get the touch
UITouch *touch = [[event touchesForView:textField1] anyObject];
// get delta
CGPoint previousLocation = [touch previousLocationInView:textField1];
CGPoint location = [touch locationInView:textField1];
CGFloat delta_x = location.x - previousLocation.x;
CGFloat delta_y = location.y - previousLocation.y;
// move button
textField1.center = CGPointMake(textField1.center.x + delta_x,textField1.center.y + delta_y);
}
- (void)moveImage:(UIPanGestureRecognizer *)recognizer
{
CGPoint newCenter = [recognizer translationInView:self.view];
if([recognizer state] == UIGestureRecognizerStateBegan) {
beginX = textField1.center.x;
beginY = textField1.center.y;
}
newCenter = CGPointMake(beginX + newCenter.x, beginY + newCenter.y);
[textField1 setCenter:newCenter];
}
- (void)viewDidUnload{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
UITextField *textFieldToRemove = [textfieldform objectAtIndex:0];
if (textFieldToRemove) {
NSLog(#"baaaaaaam! remove %i", textfieldform.count);
[textfieldform removeObject:textFieldToRemove];
[textFieldToRemove removeFromSuperview];
}
I kinda Figured it out. :)

Cocos2d Two animations for one sprite

I animate my character like that :
-(void) createHero
{
_batchNode = [CCSpriteBatchNode batchNodeWithFile:#"Snipe1.png"];
[self addChild:_batchNode];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"Snipe1.plist"];
//gather list of frames
NSMutableArray *runAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 7; ++i)
{
[runAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"run000%d.png", i]]];
}
//create sprite and run the hero
self.hero = [CCSprite spriteWithSpriteFrameName:#"run0001.png"];
_hero.anchorPoint = CGPointZero;
_hero.position = self.heroRunningPosition;
//create the animation object
CCAnimation *runAnim = [CCAnimation animationWithFrames:runAnimFrames delay:1/30.0f];
self.runAction = [CCRepeatForever actionWithAction: [CCAnimate actionWithAnimation:runAnim restoreOriginalFrame:YES]];
[_hero runAction:_runAction];
[_batchNode addChild:_hero z:0];
}
This works fine an my character is running, but now i want a second animation when he jumps. At the moment i make it like that:
-(void)changeHeroImageDuringJump
{
[_hero setTextureRect:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"run0007.png"].rect];
}
But now i want a second plist with a second png, so i get a whole new animation when the character jumps. How can i implement that ?
In my case, i implemented an AnimatedSprite class that will handle this for me. This way, I add files like so:
NSDictionary* anims = [NSDictionary dictionaryWithObjectsAndKeys:
#"Animations/Character/idle_anim.plist", #"Idle",
#"Animations/Character/walk_anim.plist", #"Walk",
#"Animations/Character/run_anim.plist", #"Run", nil];
CCNode* myNode = [[AnimatedSprite alloc] initWithDictionary:anims
spriteFrameName: #"character_idle_01.png"
startingIndex:#"Idle"];
Changing the animation is as simple as:
[myNode setAnimation: #"Run"];
Heres my implementation This is the .h
#interface AnimatedSprite : CCSprite
{
NSMutableDictionary* _spriteAnimations;
CCAction* _currentAnimation;
NSString* _currentAnimationName;
bool _initialized;
}
- (id) initWithTextureName:(NSString*) textureName;
- (id) initWithArray: (NSArray*) animList spriteFrameName: (NSString*) startingSprite startingIndex: (int)startingIndex;
- (id) initWithDictionary:(NSDictionary *)anims spriteFrameName:(NSString *)startingSprite startingIndex:(NSString *)startingAnim;
- (void) addAnimation: (NSString*) animationName andFilename: (NSString*) plistAnim;
- (void) setAnimationIndex: (int) index;
- (void) setAnimation: (NSString*) animationName;
#end
And this is the .m
#import "AKHelpers.h"
#implementation AnimatedSprite
NSMutableDictionary* _spriteAnimations;
- (id) initWithTextureName:(NSString*) textureName
{
CCTexture2D* texture = [[CCTextureCache sharedTextureCache] addImage:textureName];
CCSpriteFrame* frame = [CCSpriteFrame frameWithTexture:texture rect: CGRectMake(0, 0, 1, 1)];
if ((self=[super initWithSpriteFrame:frame]))
{
_currentAnimationName = nil;
_currentAnimation = nil;
_spriteAnimations = [[NSMutableDictionary alloc] init ];
_initialized = true;
}
return self;
}
- (id) initWithArray: (NSArray*) animList spriteFrameName: (NSString*) startingSprite startingIndex: (int)startingIndex
{
_initialized = false;
_spriteAnimations = [[NSMutableDictionary alloc] init];
// Add animations as numbers from 0 to animList.count
int i = 0;
for (NSString* anim in animList)
{
[self addAnimation: [NSString stringWithFormat:#"%d", i] andFilename:anim];
i++;
}
if ((self = [super initWithSpriteFrameName:startingSprite]))
{
_currentAnimationName = nil;
_currentAnimation = nil;
[self setAnimationIndex: startingIndex];
_initialized = true;
}
return self;
}
- (id) initWithDictionary:(NSDictionary *)anims spriteFrameName:(NSString *)startingSprite startingIndex:(NSString *)startingAnim
{
_initialized = false;
_spriteAnimations = [[NSMutableDictionary alloc] init];//[[NSMutableArray alloc] init];
// Add animations
for (NSString* key in anims)
{
[self addAnimation: key andFilename: [anims objectForKey: key] ];
}
if ((self = [super initWithSpriteFrameName:startingSprite]))
{
_currentAnimationName = nil;
_currentAnimation = nil;
[self setAnimation: startingAnim];
_initialized = true;
}
return self;
}
- (void) dealloc
{
[_currentAnimationName release];
[_spriteAnimations release];
[super dealloc];
}
- (void) setAnimation: (NSString*) animationName
{
if (![_currentAnimationName isEqualToString:animationName])
{
[_currentAnimationName release];
_currentAnimationName = [animationName copy];
// Stop current animation
if (_currentAnimation != nil)
[self stopAction:_currentAnimation];
//[self stopAllActions];
// Apply animation
NSDictionary* clip = [_spriteAnimations objectForKey: animationName];
if (clip)
{
_currentAnimation = [AKHelpers actionForAnimationClip:clip];
if (_currentAnimation)
[self runAction:_currentAnimation];
}
else
{
_currentAnimation = nil;
}
}
}
- (void) setAnimationIndex: (int) index
{
[self setAnimation: [NSString stringWithFormat:#"%d", index]];
}
- (void) addAnimation: (NSString*) animationName andFilename: (NSString*) plistAnim
{
NSDictionary *clip = [AKHelpers animationClipFromPlist:plistAnim];
if (clip)
{
[_spriteAnimations setObject:clip forKey:animationName];
if (_initialized && [_spriteAnimations count] == 1)
{
[self setAnimation:animationName];
}
}
}
#end
Create two different animation actions for running and jumping. Run those actions on need basis.

Why is my UIpageControl is not displayed?

I downloaded a dome about UIScorllView and UIPageControl. Why UIPageControl is not display?
Here is the code ,I am new in Iphone .Any help will be appreciated!
ScrollView.M I put the ResultViewController into ScrollView. I want scroll the resultViewController with PageController.
- (void)loadScrollViewWithPage:(int)page
{
if (page < 0)
return;
if (page >= pageNumber)
return;
ResultViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{
controller = [[ResultViewController alloc] initWithPageNumber:page locations:existLocations];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
existLocations = [FileManagerUtil readPlistFileForDictionary:#"Locations" fileName:#"CloudCheckLocations.plist"];
pageNumber = [existLocations count];
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < pageNumber; i++)
{
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[self.navigationItem setTitle:#"NetWork condition"];
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * pageNumber, scrollView.frame.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
pageContronl.numberOfPages = pageNumber;
pageContronl.currentPage = 0;
[pageContronl addTarget:self action:#selector(changePage:) forControlEvents:UIControlEventValueChanged];
[pageContronl setBackgroundColor:[UIColor blackColor]];
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
[scrollView addSubview:pageContronl];
[self.view addSubview:scrollView];
}
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
if (pageControlUsed)
{
return;
}
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageContronl.currentPage = page;
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
- (IBAction)changePage:(id)sender
{
int page = pageContronl.currentPage;
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
pageControlUsed = YES;
}
ScrollView.h
#interface ScrollViewController : UIViewController<UIScrollViewDelegate>
{
NSMutableArray *viewControllers;
NSString *currectNetWork;
NSString *flag;
NSString *locationName;
IBOutlet UIScrollView *scrollView;
IBOutlet UIPageControl *pageContronl;
BOOL pageControlUsed;
int pageNumber;
NSMutableDictionary *existLocations;
}
#property (nonatomic,retain) NSString *currectNetWork;
#property (nonatomic,retain) NSString *flag;
#property (nonatomic,retain) NSString *locationName;
#property (nonatomic,retain) UIPageControl * pageContronl;
#property (nonatomic,retain) UIScrollView * scrollView;
#property (nonatomic,retain) NSMutableArray *viewControllers;
#property (nonatomic,retain) NSMutableDictionary *existLocations;
(IBAction)changePage:(id)sender;
ResultViewControl.M
This method will call by ScrollView.M
- (id)initWithPageNumber:(int)page locations :(NSMutableDictionary *) locations
{
titilArray = [[NSArray alloc] initWithObjects:#"Today", #"Past 7 Day",#"Past 30 Day",nil];
if (self = [super initWithNibName:#"ResultViewController" bundle:nil])
{
pageNumber = page;
existLocations = locations;
}
return self;
}
Check the background colour of pageControl and parent view. If both have same colour (default white) page control will not display.
In IOS6, you have new methods pageIndicatorTintColor and currentPageIndicatorTintColor.
Hope this will help.
Check your top and bottom constraints of container view/ tableView(if present). Both must not be attached with Top/Bottom Layout Guide. Attach them with container Margins.

Terminate glView in cocos2d

I made an App using cocos2D that has a hierarchical structure.
And I used a UIButton on glView in a child layer.
When I get back to parent layer, the button still on it's position.
I want to terminate that.
How can I do this?
Here's the code.
MainHallLayer.m
- (id)init
{
self = [super init];
if (self != nil)
{
CCMenu *menuLists = [CCMenu menuWithItems: nil];
menuLists.position = ccp(screenSize.width/2, screenSize.height/2);
[self addChild:menuLists z:10];
NSString *fontName = [NSString stringWithFormat:#"Chalkboard SE"];
CGFloat fontSize = 28;
{
CCLabelTTF *label = [CCLabelTTF labelWithString:#"Touch Field : Getting
touches coordinates" fontName:fontName fontSize:fontSize];
[label setColor:ccc3(0.0, 0.0, 0.0)];
label.anchorPoint = ccp(0, 0.5f);
CCMenuItem *menuItem = [CCMenuItemLabel itemWithLabel:label block:^(id
sender)
{
CCScene *scene = [TouchField1Layer node];
[ReturningNode returnToNodeWithParent:scene];
[[CCDirector sharedDirector] replaceScene:scene];
}];
[menuLists addChild:menuItem];
}
}
return self;
}
ReturnToNode.m
- (id)initWithParentNode:(CCNode *)parentNode
{
self = [super init];
if (self != nil)
{
CGSize screenSize = [[CCDirector sharedDirector]winSize];
CCLabelTTF *label = [CCLabelTTF labelWithString:#" <= Return"
fontName:#"Gill Sans"
fontSize:30.0f];
label.color = ccMAGENTA;
id tint_1 = [CCTintTo actionWithDuration:0.333f red:1.0 green:.0f blue:.0f];
id tint_2 = [CCTintTo actionWithDuration:0.333f red:.5f green:.5f blue:.0f];
id tint_3 = [CCTintTo actionWithDuration:0.333f red:.0f green:1.0 blue:.0f];
id tint_4 = [CCTintTo actionWithDuration:0.333f red:.0f green:.5f blue:.5f];
id tint_5 = [CCTintTo actionWithDuration:0.333f red:.0f green:.0f blue:1.0];
id tint_6 = [CCTintTo actionWithDuration:0.333f red:.5f green:.0f blue:.5f];
id sequence = [CCSequence actions:tint_1,tint_2,tint_3,tint_4,tint_5,tint_6, nil];
id repeatAction = [CCRepeatForever actionWithAction:sequence];
[label runAction:repeatAction];
CCLayerColor *labelBackground = [CCLayerColor layerWithColor:ccc4(0.0, 0.0, 70, 40) width:label.contentSize.width + 20 height:label.contentSize.height + 20];
[label addChild:labelBackground z:-1];
CCMenuItem *menuItem = [CCMenuItemLabel itemWithLabel:label block:^(id sender)
{
[self removeFromParentAndCleanup:YES];
[[CCDirector sharedDirector] replaceScene:[TouchControllerLayer scene]];
}];
CCMenu *menu = [CCMenu menuWithItems:menuItem, nil];
[menu alignItemsVertically];
menu.position = CGPointMake(label.contentSize.width/2 , screenSize.height - 20);
[self addChild:menu];
[parentNode addChild:self z:1000];
}
return self;
}
+ (id)returnToNodeWithParent:(CCNode *)parentNode
{
return [[[self alloc] initWithParentNode:parentNode] autorelease];
}
TouchField1Layer.m
- (id)init
{
self = [super init];
if (self != nil)
{
BackgroundLayer *background = [BackgroundLayer node];
TouchField3Layer *layer = [TouchField3Layer node];
[self addChild:background z:3];
[self addChild:layer z:2];
[self preparingTools];
}
return self;
}
- (void)preparingTools
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(0, 0, 100, 40);
UIView *glView = [CCDirector sharedDirector].openGLView;
glView.tag = TAG_GLVIEW;
[glView addSubview:button];
}
Any advices, helps are welcome. Always thanks. Bless You.
If you add UIKit views you will have to remove them manually at the appropriate point in time. Cocos2D does not manage the lifetime of UIKit views, only classes derived from CCNode.
For example when changing scenes you will have to remove the UIButton from the glView either in -(void) dealloc or in -(void) cleanup.

Get UITableView to scroll to the selected UITextField and Avoid Being Hidden by Keyboard

I have a UITextField in a table view on a UIViewController (not a UITableViewController).
If the table view is on a UITableViewController, the table will automatically scroll to the textField being edited to prevent it from being hidden by the keyboard. But on a UIViewController it does not.
I have tried for a couple of days reading through multiple ways to try to accomplish this and I cannot get it to work. The closest thing that actually scrolls is:
-(void) textFieldDidBeginEditing:(UITextField *)textField {
// SUPPOSEDLY Scroll to the current text field
CGRect textFieldRect = [textField frame];
[self.wordsTableView scrollRectToVisible:textFieldRect animated:YES];
}
However this only scrolls the table to the topmost row.
What seems like an easy task has been a couple of days of frustration.
I am using the following to construct the tableView cells:
- (UITableViewCell *)tableView:(UITableView *)aTableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = [NSString stringWithFormat: #"%d:%d", [indexPath indexAtPosition: 0], [indexPath indexAtPosition:1]];
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:identifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
UITextField *theTextField = [[UITextField alloc] initWithFrame:CGRectMake(180, 10, 130, 25)];
theTextField.adjustsFontSizeToFitWidth = YES;
theTextField.textColor = [UIColor redColor];
theTextField.text = [textFieldArray objectAtIndex:indexPath.row];
theTextField.keyboardType = UIKeyboardTypeDefault;
theTextField.returnKeyType = UIReturnKeyDone;
theTextField.font = [UIFont boldSystemFontOfSize:14];
theTextField.backgroundColor = [UIColor whiteColor];
theTextField.autocorrectionType = UITextAutocorrectionTypeNo;
theTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
theTextField.clearsOnBeginEditing = NO;
theTextField.textAlignment = UITextAlignmentLeft;
//theTextField.tag = 0;
theTextField.tag=indexPath.row;
theTextField.delegate = self;
theTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
[theTextField setEnabled: YES];
[cell addSubview:theTextField];
[theTextField release];
}
return cell;
}
I suspect I can get the tableView to scroll properly if I can somehow pass the indexPath.row in the textFieldDidBeginEditing method?
Any help is appreciated.
In my app, I have successfully used a combination of contentInset and scrollToRowAtIndexPath like this:
When you want to display the keyboard, just add a contentInset at the bottom with your table with desired height:
tableView.contentInset = UIEdgeInsetsMake(0, 0, height, 0);
Then, you can safely use
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:cell_index inSection:cell_section] animated:YES];
By adding the contentInset, even if you are focusing on the last cell the tableView will still be able to scroll. Just make sure that when you are dismissing the keyboard, you reset the contentInset.
EDIT:
If you have only one section (you can replace cell_section with 0) and the use the textView tag to inform the cell row.
Swift
#objc private func keyboardWillShow(_ notification: Notification) {
guard let userinfo = notification.userInfo else {
return
}
guard
let duration = (userinfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue,
let endFrame = (userinfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
let curveOption = userinfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else {
return
}
UIView.animate(withDuration: duration, delay: 0, options: [.beginFromCurrentState, .init(rawValue: curveOption)], animations: {
let edgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: endFrame.height, right: 0)
self.scrollView.contentInset = edgeInsets
self.scrollView.scrollIndicatorInsets = edgeInsets
})
}
#objc private func keyboardWillHide(_ notification: Notification) {
guard let userinfo = notification.userInfo else {
return
}
guard
let duration = (userinfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue,
let curveOption = userinfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else {
return
}
UIView.animate(withDuration: duration, delay: 0, options: [.beginFromCurrentState, .init(rawValue: curveOption)], animations: {
let edgeInsets = UIEdgeInsets.zero
self.scrollView.contentInset = edgeInsets
self.scrollView.scrollIndicatorInsets = edgeInsets
})
}
override func viewDidLoad() {
super.viewDidLoad()
// ...
subscribeToKeyboardNotifications()
}
deinit {
unsubscribeFromKeyboardNotifications()
}
private func subscribeToKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIWindow.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIWindow.keyboardWillHideNotification, object: nil)
}
private func unsubscribeFromKeyboardNotifications() {
NotificationCenter.default.removeObserver(self, name: UIWindow.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIWindow.keyboardWillHideNotification, object: nil)
}
Objective C
- (void)keyboardWillShow:(NSNotification *)sender
{
CGFloat height = [[sender.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
NSTimeInterval duration = [[sender.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationOptions curveOption = [[sender.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue] << 16;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState|curveOption animations:^{
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(0, 0, height, 0);
tableView.contentInset = edgeInsets;
tableView.scrollIndicatorInsets = edgeInsets;
} completion:nil];
}
- (void)keyboardWillHide:(NSNotification *)sender
{
NSTimeInterval duration = [[sender.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationOptions curveOption = [[sender.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue] << 16;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState|curveOption animations:^{
UIEdgeInsets edgeInsets = UIEdgeInsetsZero;
tableView.contentInset = edgeInsets;
tableView.scrollIndicatorInsets = edgeInsets;
} completion:nil];
}
And in - (void)viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Then
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
This is a tweak to FunkyKat's answer (big thank you FunkyKat!). It would probably be beneficial to not hardcode UIEdgeInsetsZero for future iOS compatibility.
Instead, I ask for the current inset value and tweak the bottom value as needed.
- (void)keyboardWillShow:(NSNotification *)sender {
CGSize kbSize = [[[sender userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
NSTimeInterval duration = [[[sender userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGFloat height = UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]) ? kbSize.height : kbSize.width;
if (isIOS8()) height = kbSize.height;
[UIView animateWithDuration:duration animations:^{
UIEdgeInsets edgeInsets = [[self tableView] contentInset];
edgeInsets.bottom = height;
[[self tableView] setContentInset:edgeInsets];
edgeInsets = [[self tableView] scrollIndicatorInsets];
edgeInsets.bottom = height;
[[self tableView] setScrollIndicatorInsets:edgeInsets];
}];
}
- (void)keyboardWillHide:(NSNotification *)sender {
NSTimeInterval duration = [[[sender userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration animations:^{
UIEdgeInsets edgeInsets = [[self tableView] contentInset];
edgeInsets.bottom = 0;
[[self tableView] setContentInset:edgeInsets];
edgeInsets = [[self tableView] scrollIndicatorInsets];
edgeInsets.bottom = 0;
[[self tableView] setScrollIndicatorInsets:edgeInsets];
}];
}
For the sake of anyone else running into this issue, I'm posting the necessary methods here:
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = [NSString stringWithFormat: #"%d:%d", [indexPath indexAtPosition: 0], [indexPath indexAtPosition:1]];
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
UITextField *theTextField = [[UITextField alloc] initWithFrame:CGRectMake(180, 10, 130, 25)];
theTextField.keyboardType = UIKeyboardTypeDefault;
theTextField.returnKeyType = UIReturnKeyDone;
theTextField.clearsOnBeginEditing = NO;
theTextField.textAlignment = UITextAlignmentLeft;
// (The tag by indexPath.row is the critical part to identifying the appropriate
// row in textFieldDidBeginEditing and textFieldShouldEndEditing below:)
theTextField.tag=indexPath.row;
theTextField.delegate = self;
theTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
[theTextField setEnabled: YES];
[cell addSubview:theTextField];
[theTextField release];
}
return cell;
}
-(void) textFieldDidBeginEditing:(UITextField *)textField {
int z = textField.tag;
if (z > 4) {
// Only deal with the table row if the row index is 5
// or greater since the first five rows are already
// visible above the keyboard
// resize the UITableView to fit above the keyboard
self.wordsTableView.frame = CGRectMake(0.0,44.0,320.0,200.0);
// adjust the contentInset
wordsTableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 10);
// Scroll to the current text field
[wordsTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:z inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
// Determine which row is being edited
int z = textField.tag;
if (z > 4) {
// resize the UITableView to the original size
self.wordsTableView.frame = CGRectMake(0.0,44.0,320.0,416.0);
// Undo the contentInset
wordsTableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// Dismisses the keyboard when the "Done" button is clicked
[textField resignFirstResponder];
return YES;
}
I needed a simple solution so for me helped:
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
let pointInTable = textField.superview!.convert(textField.frame.origin, to: tableView)
var tableVContentOffset = tableView.contentOffset
tableVContentOffset.y = pointInTable.y
if let accessoryView = textField.inputAccessoryView {
tableVContentOffset.y -= accessoryView.frame.size.height
}
tableView.setContentOffset(tableVContentOffset, animated: true)
return true;
}
Try my coding, this will help for ypu
tabelview.contentInset = UIEdgeInsetsMake(0, 0, 210, 0);
[tableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:your_indexnumber inSection:Your_section]
atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
Apple has an official post explaining how to do this naturally as they do in the UITableViewController. My Stackoverflow answer has this explained along with a swift version.
https://stackoverflow.com/a/31869898/1032179
You need to resize the tableView itself so that it does not go under the keyboard.
-(void) textFieldDidBeginEditing:(UITextField *)textField {
// SUPPOSEDLY Scroll to the current text field
self.worldsTableView.frame = CGRectMake(//make the tableView smaller; to only be in the area above the keyboard);
CGRect textFieldRect = [textField frame];
[self.wordsTableView scrollRectToVisible:textFieldRect animated:YES];
}
Alternatively, you can use a keyboard notification; this works slightly better because you have more information, and is more consistent in terms of knowing when the keyboard is coming up:
//ViewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
And then implement:
- (void)keyboardWillShow:(NSNotification *)notification {
}
- (void)keyboardWillHide:(NSNotification *)notification {
}
My code. Maybe someone will be useful:
Custom textField cell in tableView
.m
#property (nonatomic, strong) UITextField *currentCellTextField;
CustomCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
NSArray * nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = (CustomCell *)[nib objectAtIndex:0];
cell.textfield.delegate = self;
}
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
self.currentCellTextField = textField;
CGPoint pnt = [self.organisationTableView convertPoint:textField.bounds.origin fromView:textField];
NSIndexPath* path = [self.organisationTableView indexPathForRowAtPoint:pnt];
if (path.section >= 2) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
self.organisationTableView.contentInset = UIEdgeInsetsMake(0, 0, kOFFSET_FOR_KEYBOARD, 0);
CGPoint siize = self.organisationTableView.contentOffset;
siize.y =(pnt.y-170);
self.organisationTableView.contentOffset = CGPointMake(0, siize.y);
[UIView commitAnimations];
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
CGPoint pnt = [self.organisationTableView convertPoint:textField.bounds.origin fromView:textField];
NSIndexPath* path = [self.organisationTableView indexPathForRowAtPoint:pnt];
if (path.section >= 2) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
self.organisationTableView.contentInset = UIEdgeInsetsZero;
self.organisationTableView.contentOffset = CGPointMake(0, self.organisationTableView.contentOffset.y);
[UIView commitAnimations];
}
return YES;
}
In my case my UITableview was inside another UIView and that UIvie was in the main UIScrollview. So I used more general solution for those kind of problems.
I simply found the Y coordinate of my cell in the specific UIScrollView and then scrolled to correct point:
-(void)textFieldDidBeginEditing:(UITextField *)textField{
float kbHeight = 216;//Hard Coded and will not support lanscape mode
UITableViewCell *cell = (UITableViewCell *)[textField superview];
float scrollToHeight = [self FindCordinate:cell];
[(UIScrollView *)self.view setContentOffset:CGPointMake(0, scrollToHeight - kbHeight + cell.frame.size.height) animated:YES];
}
-(float)FindCordinate:(UIView *)cell{
float Ycordinate = 0.0;
while ([cell superview] != self.view) {
Ycordinate += cell.frame.origin.y;
cell = [cell superview];
}
Ycordinate += cell.frame.origin.y;
return Ycordinate;
}
Another simple solution is adding an additional space for the footer of the last table section:
- (float)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if (section == lastSection) {
return keyboard height;
}
return 0;
}
We can add our icon into this area as well. :)
You can try adding a UITableViewController to the UIViewController instead of just a table view. This way you can call UITableViewController's viewWillAppear and everything will appear to work.
Example:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[tableViewController viewWillAppear:animated];
}
I have add a little feature to #FunkyKat and #bmauter answers (great answer by the way, it should be the one accepted)
The regular Table View edge insets is preserved, before/after the keyboard apparition.
- (void)keyboardWillShow:(NSNotification *)sender
{
CGSize kbSize = [[[sender userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
NSTimeInterval duration = [[[sender userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGFloat height = UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]) ? kbSize.width : kbSize.height;
[UIView animateWithDuration:duration animations:^{
UIEdgeInsets edgeInsets = self.tableView.contentInset;
edgeInsets.bottom += height;
self.tableView.contentInset = edgeInsets;
edgeInsets = self.tableView.scrollIndicatorInsets;
edgeInsets.bottom += height;
self.tableView.scrollIndicatorInsets = edgeInsets;
}];
}
- (void)keyboardWillHide:(NSNotification *)sender
{
CGSize kbSize = [[[sender userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
NSTimeInterval duration = [[[sender userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGFloat height = UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]) ? kbSize.width : kbSize.height;
[UIView animateWithDuration:duration animations:^{
UIEdgeInsets edgeInsets = self.tableView.contentInset;
edgeInsets.bottom -= height;
self.tableView.contentInset = edgeInsets;
edgeInsets = self.tableView.scrollIndicatorInsets;
edgeInsets.bottom -= height;
self.tableView.scrollIndicatorInsets = edgeInsets;
}];
}

Resources