UIScrolllView and info button - objective-c

I have custom UIViewController which looks like this.
#implementation UIViewControllerCustom
- (id)init
{
self = [super init];
if (self) {
NSLog(#"init");
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[infoButton setFrame:CGRectMake(290, 10, 16, 16)];
[infoButton addTarget:self action:#selector(showInfo) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:infoButton];
}
-(void)showInfo
{
About *about = [[About alloc]init];
NSLog(#"touched");
[about setModalTransitionStyle:UIModalPresentationFullScreen];
[self presentModalViewController:about animated:YES];
}
#end
Any view controller in my app inherits this controller. When info button is touched the modal window is present. The problem is that one of my view controllers use UIScrollView. In this controller info button is visible and it reacts on touches. The problem is that when I touch the button showInfo method of UIViewControllerCustom is not called. I have no such a problem in the other controller.
What can be wrong here ?

Because the UIScrollView handles the message being sent. In your case the touch on the button will be handled by the UIScrollView.
I would suggest you to subclass the UIScrollView and implement: - (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view to determine if the UIScrollView should handle the event or not.
The implementation could be something along the lines of:
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
if ([view isKindOfClass:[UIButton class]]) {
return NO;
}
return YES;
}

Related

Methods in another scene not called

The 'thePlay' gets presented but does not display the redColor background. It remains black. Can someone advice on what I am supposed to do.
More Clarification: All the scenes and quickMenu class are imported on each other
This method execute transition from this scene(gameScene) using a button in quickMenu class (subclass of SKNode)
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches){
if (self.gameEnded && quickMenu.touchable) {
SKNode *theNode = [quickMenu nodeAtPoint:[touch locationInNode:quickMenu]];
if ([theNode.name isEqualToString:#"theMenu"]){
SKScene *thePlay = [[SKScene alloc] initWithSize:self.size];
SKTransition *doors = [SKTransition doorsOpenHorizontalWithDuration:1.0];
[self.view presentScene:thePlay transition:doors];
}
}
}
}
this is the first method in another scene (thePlay scene),
-(void)didMoveToView:(SKView *)view
{
self.backgroundColor = [SKColor redColor];
NSLog(#"this method called");
}
I tried the init method, did not show the redColor background as well, as shown below...
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size]) {
self.backgroundColor = [SKColor redColor];
NSLog(#"init method called");
}
Am I missing something?

Why do my touch event not work?

I have declared a void touchesbegan method in my controller but it doesn't work! i don't know why. i have an image view which i plan to click it to move to next controller. so i set the touches began method. i have linked the image view in the xib file but when i click the image. nothing happens. Please help, Thanks.
ViewController.h
#import <UIKit/UIKit.h>
#interface imageViewViewController : UIViewController
{
IBOutlet UIImageView *testing;
}
#property(nonatomic, retain) IBOutlet UIImageView *testing;
#end
ViewController.m
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if(touch.view == testing)
{
TestViewController *testviewcontroller = [[TestViewController alloc]initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:testviewcontroller animated:YES];
}
}
#end
P.S.
here i tried another method using tap gestures.
testing is the name of my image view. as u can see i comment out the ns log in the imagedidtapped method. it works til that point. however when i tried to navigate it out to another page it fails.
- (void)viewDidLoad
{
UITapGestureRecognizer *tapRecognizer;
[testing setTag:0];
[testing setUserInteractionEnabled:TRUE];
tapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageViewDidTapped:)] autorelease];
tapRecognizer.numberOfTapsRequired = 1;
[testing addGestureRecognizer:tapRecognizer];
[self.view addSubview:testing];
[testing release];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)imageViewDidTapped:(UIGestureRecognizer *)aGesture {
UITapGestureRecognizer *tapGesture = (UITapGestureRecognizer *)aGesture;
UIImageView *tappedImageView = (UIImageView *)[tapGesture view];
switch (tappedImageView.tag) {
case 0:
//NSLog(#"UIImageView 1 was tapped");
[self navigate];
break;
case 1:
NSLog(#"UIImageView 2 was tapped");
break;
default:
break;
}
}
-(void)navigate
{
TestViewController *testviewcontroller = [[TestViewController alloc]initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:testviewcontroller animated:YES];
}
The problem is that by default userInteractionEnabled is NO for a UIImageView so you won't get any touches. Set it to YES.
Also the message handling for touchesBegan is really complicated. You'll be much happier if you attach a UITapGestureRecognizer to the image view.
EDIT: Now you say your touches handling is working, but the navigation is not taking place. So let's concentrate on this part of your code:
-(void)navigate
{
TestViewController *testviewcontroller = [[TestViewController alloc]initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:testviewcontroller animated:YES];
}
Put logging in there to make sure navigate is being called! If it isn't being called, you need to figure out why your other code is not running and calling it. If it is being called, then the problem is probably that self.navigationController is nil, i.e. you are not inside a navigation interface to start with.

Xcode keyboard issue on scroll view

I have a scroll view on top single view. I have some textfields and UIPickers on it. Now I know how to make a keyboard go off when return is pushed. But, I am trying to get the keyboard off from textfield when the background is tapped or UIpicker is selected. I tried doing this...
Interface :
- (IBAction)textFieldReturn:(id)sender;
- (IBAction)backgroundTouched:(id)sender;
Implementation :
-(IBAction)textFieldReturn:(id)sender
{
[sender resignFirstResponder];
}
-(IBAction)backgroundTouched:(id)sender
{
[textField resignFirstResponder];
}
But the problem is I cant make sroll view as control type to make it work..
Try like this may be it helps you but not sure,
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
if (![[touch view] isKindOfClass:[UITextField class]]) {
[yourtextfield resignFirstResponder];
}
}
And for getting touch event on scrollview you have to take geasture recognization,
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTap)];
[scroll addGestureRecognizer:singleTap];
-(void)singleTap{
[text resignFirstResponder];
//write whatever you want it.
}

dismissing the keyboard from a UITextField,UITextView as a subview of UIScrollView?

I have an application with UIScrollView added as a subview of UIView. i have added UITextField,UITextview as a subView of UIScrollView .I want to dismiss the keyboard when i tap in the scroll view. how can i do this?
Just add UITapGestureRecognizer
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[scr addGestureRecognizer:singleTap];
}
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
//Get touch point
CGPoint touchPoint=[gesture locationInView:scr];
//Hide keyBoard
[self.view endEditing:YES];
}
In iOS 7, you can achieve this easily.
scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
Try this,
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
tapGesture.cancelsTouchesInView = NO;
[scrollView addGestureRecognizer:tapGesture];
[tapGesture release];
}
-(void)dismissKeyboard
{
[txtNotes resignFirstResponder];
[textView resignFirstResponder];
}
When I added the gesture to a subclass of UIScrollView, I was having problems with the various gestures in my view tree interfering with each other, such as being able to click on subviews, scroll the view, and have the keyboard dismiss in all cases. I came up with this solution, which can be setup from a superclass of UIScrollView or from a UIViewController.
The DismissKeyboardTapGesture class uses ARC, works with any text fields under the view, and doesn't take over any clicks from subviews like buttons. Also takes advantage of iOS7 scrolling effect to dismiss keyboard.
Setting up from UISScrollView superclass:
_dismissKeyboard = [[DismissKeyboardTapGesture alloc] initWithView:self];
or from UIViewController:
_dismissKeyboard = [[DismissKeyboardTapGesture alloc] initWithView:self.view];
Here is the class:
#interface DismissKeyboardTapGesture : NSObject <UIGestureRecognizerDelegate>
#end
#implementation DismissKeyboardTapGesture
- (id)initWithView:(UIView *)view
{
self = [super init];
if (self) {
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTap:)];
singleTap.cancelsTouchesInView = NO;
singleTap.delegate = self;
[view addGestureRecognizer:singleTap];
if ([view respondsToSelector:#selector(setKeyboardDismissMode:)]) {
// Bonus effect to dismiss keyboard by scrolling
((UIScrollView *)view).keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
}
}
return self;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// Don't stop any existing gestures in our view from working
if (otherGestureRecognizer.view == gestureRecognizer.view) {
return YES;
}
return NO;
}
- (void)singleTap:(UIGestureRecognizer*)gestureRecognizer
{
// Close keyboard for any text edit views that are children of the main view
[gestureRecognizer.view endEditing:YES];
}
#end

Getting touches for a view with subview

i want to have a top view (subclass of UIView), which catches touches using
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
...
.h
#interface XView : UIView<UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UITableView * tableView;
#end
this works fine, if the view is empty, but as soon as i insert (addSubview) lets say a UITableView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.tableView = [[UITableView alloc] initWithFrame:self.frame];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self addSubview:self.tableView];
}
return self;
}
Than the touch methods inside XView are not triggered
You would either need to subclass your UITableView or use a UITapGestureRecognizer to solve this. I'd personally go with the UITapGestureRecognizer.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapCode:)];
[self.tableView addGestureRecognizer:tap];
and then you can handle your tap here:
- (void)tapCode:(UITapGestureRecognizer *)recognizer
{
// code goes here
}
If you subclass UITableView, you can put your touchesBegan:withEvent in there.