UITapGestureRecognizer Error, when I add to an imageview - iphone

I use UITapGestureRecognizer to handle An ImageviewTap actions. In the main ViewController it works great. But when i Use another ViewController in my APP, and copy the same UITapRecognizer code I get an EXC_BAD_ACCESS code=1 address: 0x80759d3a error message to the line when i add the recognizer to my imageview. What do I wrong?
My ImageView: It works
UIImageView *live;
live = [[UIImageView alloc]initWithFrame:CGRectMake(92, 230, 136, 100)];
live.image = [UIImage imageNamed:#"online.png"];
[live addSubview:onlineLabel2];
[live setUserInteractionEnabled:YES];
[self.view addSubview:live];
[super viewDidLoad];
and my Gesture Recognizer:
UITapGestureRecognizer *singleTaP3 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onlineTap:)];
singleTaP3.numberOfTapsRequired = 1;
singleTaP3.numberOfTouchesRequired = 1;
[live addGestureRecognizer:singleTaP3];
and the last line i get the crash.

It sounds like your live view is not retain, so when you try to add the gesture, the view doesn't exist anymore. Try to record your live view as a property in your interface, and synthetise it in your implementation.

I am not sure if that this causing you to crash your code but you should call
[super viewDidLoad];
at the start of the code. (If you are using ARC than this looks fine.)
[super viewDidLoad];
UIImageView *live;
live = [[UIImageView alloc]initWithFrame:CGRectMake(92, 230, 136, 100)];
live.image = [UIImage imageNamed:#"online.png"];
[live addSubview:onlineLabel2];
[live setUserInteractionEnabled:YES];
[self.view addSubview:live];

I test the following and it works.
The interface:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) UIView *v;
- (void)tapAction;
#end
And the implementation:
#import "ViewController.h"
#implementation ViewController
#synthesize v=_v;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_v = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
[_v setBackgroundColor:[UIColor redColor]];
[self.view addSubview:_v];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapAction)];
tap.numberOfTouchesRequired = 1;
tap.numberOfTapsRequired = 1;
[_v addGestureRecognizer:tap];
}
- (void)tapAction
{
NSLog(#"tap tap");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

My problem was in my main viewcontroller. I called the new viewcontroller wrong, and get nullpointer for it. Get it in property, and it works. The problem is not with gesturetaprecognizer.

Related

Touch events not passing to subviews

i have a scrollview and inside a uiview that contains multiple subviews ( uiimageview). the problem is i can't pass touch gestures to the imageviews ..
#interface photoLibrary (){
UIView *view_cuImagini;
}
#property (nonatomic,retain) UIScrollView *scrl_images;
#end
#implementation photoLibrary
#synthesize scrl_images;
//..
- (void)viewDidLoad{
[super viewDidLoad];
//...
scrl_images.minimumZoomScale=0.4;
view_cuImagini=[[UIView alloc]initWithFrame:CGRectMake(scrl_images.frame.origin.x, scrl_images.frame.origin.y, scrl_images.frame.size.width, scrl_images.frame.size.height)];
view_cuImagini.backgroundColor=[UIColor blackColor];
[scrl_images addSubview:view_cuImagini];
}
-(void)AddImageViewWithFrame:(CGRect)frame andImage:(UIImage*)img andtag:(int)tag{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
tempimg=[[UIImageView alloc] initWithFrame:frame];
UIImageView *bifat = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bifat.jpg"]];
tempimg.image=img;
tempimg.tag=tag;
tap.delegate=self;
tempimg.userInteractionEnabled = YES;
view_cuImagini.userInteractionEnabled=YES;
[tempimg addGestureRecognizer:tap];
// [self.view addGestureRecognizer:tap];
[tempimg addSubview:bifat];
[view_cuImagini addSubview:tempimg];
}
-(void)imageTapped:(UITapGestureRecognizer *)rec{
if (rec.state==UIGestureRecognizerStateRecognized) {
NSLog(#"imageTouch with tag %i",rec.view.tag);
}
i want to be able to find the which tempimg was touched
does anybody has a solutions for this?

Adding ActivityIndicator to Webview Tab app

I'm trying to add a "loading" indicator in the center of my screen after each tab is selected and as the initial tab is loaded. I have found many posts showing the code to accomplish this but it doesn't seem to work with the way my webview app is setup.
I am a novice and have written all of my code from different tutorials, so If you could please explain where to put the code that would be helpful.
Here is my current .h file
#import <UIKit/UIKit.h>
#interface ViewController1 : UIViewController
{
IBOutlet UIWebView *myWebView;
}
#end
Here is my current .m file
#import "ViewController1.h"
#interface ViewController1 ()
#end
#implementation ViewController1
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Home", #"Home");
self.tabBarItem.image = [UIImage imageNamed:#"birdhouse"];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
{
UIImage *navigationBarBackground = [[UIImage imageNamed:#"navbar.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:navigationBarBackground forBarMetrics:UIBarMetricsDefault];
}
// Do any additional setup after loading the view from its nib.
NSURL *myURL = [NSURL URLWithString:#"http://jbirdmedia.org/rcwc/iphone/home.html"];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myURL];
[myWebView loadRequest:myRequest];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I've taken out all the code from my failed attempts so this code is currently my working app for viewcontroller1 and I have 4 ViewControllers for my 4 tabs.
Thanks,
Jason
Well your code right now doesn't mention anything about an UIActivityIndicatorView. In your viewDidLoad method you need something like this:
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityView.center = myWebView.center;
[myWebView addSubview: activityView];
[activityView startAnimating];
This is very rough and not tested but it should look something like this:
UIView *loadingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 150)];
loadingView.center = self.view.center;
[loadingView setBackgroundColor:[UIColor blackColor]];
[loadingView setAlpha:0.75f];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.frame = CGRectMake(0,0,40,40);
activityIndicator.center = loadingView.center;
[loadingView addSubview:activityIndicator];
[activityIndicator startAnimating];
UILabel *loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, loadingView.bounds.size.width, 50)];
[loadingLabel setText:#"Loading"];
[loadingLabel setBackgroundColor:[UIColor clearColor]];
[loadingLabel setTextAlignment:NSTextAlignmentCenter];
[loadingLabel setTextColor:[UIColor whiteColor]];
[loadingView addSubview:loadingLabel];
[self.webView addSubview:loadingView];
You'll need to adapt for the way you actually want the views to look, but that should get you pointed in the right direction.

Set title to implemented UINavigationBar

My code:
#interface BIDMyClass ()
#end
#implementation BIDMyClass {
UINavigationBar *settingsBar;
}
-(void)loadView {
[super loadView];
settingsBar = [[UINavigationBar alloc] init];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[settingsBar setFrame:CGRectMake(0.0f, 0.0f, 293.0f, 44.0f)];
[settingsBar.topItem setTitle:#"Settings"];
[self.view addSubview:settingsBar];
}
settingsBar is added but there is no title on it. How can I fix it?
settingsBar.topItem is probably nil. Try setting the list of items on your settingsBar:
settingsBar.items = [NSArray arrayWithObject:[[[UINavigationItem alloc] initWithTitle:#"Settings"] autorelease]];
Alternatively you may also declare your:
IBOutlet UINavigationBar *navBar;
and connect in IB. Assuming you have an XIB file with the navBar on it.

Bar Button Item unable to work

-(IBAction)startClick:(id)sender{
stick.highlighted = YES;
}
-(void)viewDidLoad{
[super viewDidLoad];
stick = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"ball1.png"]];
stick.userInteractionEnabled= YES;
stick.highlightedImage = [UIImage imagedNamed:#"ball2.png"];
[self.view addSubview:stick];
}
Button does not work after i type viewDidLoad method. Pls help. Thx. stick is linked to a uiimageview.
Hello as you said stick is linked to UIImageView , then it is a bit ambiguous. It's not clear whether you have declared an IBOutlet for this and connected to an UIImageview in xib or you have declared it as a variable in header file . There are two methods both of which works fine
Method 1:
Declare an IBoutlet in .h file and connect it to an Imageview in xib . Calling methods as follows
-(void)viewDidLoad{
[super viewDidLoad];
stick.image = [UIImage imageNamed:#"firstImage.png"];
stick.highlightedImage = [UIImage imageNamed:#"secondImage.png"];
}
-(IBAction)startClick:(id)sender{
stick.highlighted = YES;
}
would serve your purpose. The method is called from a button in xib on touch up inside event. In case you want to call this method from bar button all you need is to hook up selector of bar button to startclick method.
//2nd Method
If you have declared your Imageview in header as UIImageView* stick;
in viewDidLoad method you need to allocate it as
-(void)viewDidLoad{
[super viewDidLoad];
if (!stick) {
stick = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
[stick setImage:[UIImage imageNamed:#"firstImage.png"]];
[stick setHighlightedImage:[UIImage imageNamed:#"secondImage.png"]];
}
UIBarButtonItem* barButton = [[UIBarButtonItem alloc] initWithTitle:#"Click" style:UIBarButtonItemStylePlain
target:self action:#selector(startClick:)];
self.navigationItem.rightBarButtonItem = barButton;
[barButton release];
}
-(void)startClick:(id)sender{
stick.highlighted = YES;
}
Hope it helps !!
might be due to :
-(void)viewDidLoad
{
[super viewDidLoad];
stick = [UIImageView alloc]initWithImage:[UIImage imageNamed:#"ball1.png"];
stick.userInteractionEnabled= YES;
// stick.highlightedImage = [UIImage imaged:#"ball2.png"];
stick.highlightedImage = [UIImage imageNamed:#"ball2.png"];
[self.view addSubview:stick];
}

Switching custom views programmatically (pushing and popping)

In iOS, my views work individually but I can't switch between them.
Now after a lot of google-ing around I've fond that the navigation based app would work great with the stack for views. The problem is all my views are nib/xib-less and custom tailored in the source code. Because of that I need my own UINavigationController and push and pop views by hand/code. Since every tutorial is either nib/xib and IB bound or just a mash of code snippets I need a concrete example how to do it.
A simple example with 2 programmatically created view (can be empty just have to use loadView instead of initializing with a nib/xib) and a working stack (a push and a pop of the views like: load app,create some root view if needed, push one view and from that view push the second one and then pop them) would be awesome, or at least a tutorial in that way with the whole source of the project and not snippets.
Thanks in advance.
EDIT: After some extra thinking, a little more clarification wouldn't be bad. My app will basically consist of 5 or 6 views which will be called form their respective previous view, i.e. a drill-down app.
Here's a brief code, only the essential parts:
CodeViewsPushingAppDelegate.m
#import "CodeViewsPushingAppDelegate.h"
#import "ViewNumberOne.h"
#implementation CodeViewsPushingAppDelegate
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
UINavigationController *navController = [[UINavigationController alloc] init];
ViewNumberOne *view1 = [[ViewNumberOne alloc] init];
[navController pushViewController:view1 animated:NO];
[self.window addSubview:navController.view];
[self.window makeKeyAndVisible];
return YES;
}
ViewNumberOne.h
#import <UIKit/UIKit.h>
#interface ViewNumberOne : UIViewController
{
UIButton *button;
}
- (void)pushAnotherView;
#end
ViewNumberOne.m
#import "ViewNumberOne.h"
#import "ViewNumberTwo.h"
#implementation ViewNumberOne
- (void)loadView
{
[super loadView];
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(110, 190, 100, 20);
[button setTitle:#"Push Me!" forState:UIControlStateNormal];
[button addTarget:self action:#selector(pushAnotherView) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)pushAnotherView;
{
ViewNumberTwo *view2 = [[ViewNumberTwo alloc] init];
[self.navigationController pushViewController:view2 animated:YES];
[view2 release];
}
ViewNumberTwo.h
#import <UIKit/UIKit.h>
#interface ViewNumberTwo : UIViewController
{
UILabel *label;
}
#end
ViewNumberTwo.m
#import "ViewNumberTwo.h"
#implementation ViewNumberTwo
- (void)loadView
{
[super loadView];
label = [[UILabel alloc] init];
label.text = #"I am a label! This is view #2";
label.numberOfLines = 2;
label.textAlignment = UITextAlignmentCenter;
label.frame = CGRectMake(50, 50, 200, 200); //whatever
[self.view addSubview:label];
}