Cannot set action on UIBarButtonItem - iphone

So I'm adding a bunch of custom UIBarButtonItems to a UIToolbar, and they all load just fine and look great, and I can see them in my UIToolbar. The only problem is, I can't perform any actions on them. In my viewDidLoad, I set up everything. Here are my .h and .m files:
.h file:
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <QuartzCore/QuartzCore.h>
#interface PhotoEditViewController : UIViewController <UIPopoverControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIGestureRecognizerDelegate> {
IBOutlet UIImageView *imageView;
}
- (IBAction)cancelEdit:(id)sender;
- (IBAction)savePhoto:(id)sender;
- (IBAction)chooseColor:(id)sender;
#property (retain) IBOutlet UIToolbar *editBar;
#property (retain) UIImageView *imageView;
#property (retain) UIImage *tempImage;
- (void) setupStache;
#end
.m file: (viewDidLoad)
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.image = tempImage;
NSMutableArray *toolbarItems = [NSMutableArray arrayWithCapacity:3];
// get the filepaths of all the images
NSString *imagePath_cancel = [[NSBundle mainBundle] pathForResource:#"barBtnPhotoEditCancel" ofType:#"png"];
NSString *imagePath_save = [[NSBundle mainBundle] pathForResource:#"barBtnSavePhoto" ofType:#"png"];
NSString *imagePath_color = [[NSBundle mainBundle] pathForResource:#"barBtnChangeColor" ofType:#"png"];
// get the images
UIImage *cancelImage = [[UIImage alloc] initWithContentsOfFile:imagePath_cancel];
UIImage *saveImage = [[UIImage alloc] initWithContentsOfFile:imagePath_save];
UIImage *changeColorImage = [[UIImage alloc] initWithContentsOfFile:imagePath_color];
// set the images to the UIBarButtonItem(s)
CGRect cancelFrame = CGRectMake(0, 0, cancelImage.size.width-25, cancelImage.size.height-25);
UIButton* cancelButton = [[UIButton alloc] initWithFrame:cancelFrame];
[cancelButton setBackgroundImage:cancelImage forState:UIControlStateNormal];
[cancelButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *cancelBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:cancelButton];
[cancelBarButtonItem setTarget:self];
[cancelBarButtonItem setAction:#selector(cancelEdit:)];
CGRect saveFrame = CGRectMake(0, 0, saveImage.size.width-25, saveImage.size.height-25);
UIButton* saveButton = [[UIButton alloc] initWithFrame:saveFrame];
[saveButton setBackgroundImage:saveImage forState:UIControlStateNormal];
[saveButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem* saveBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:saveButton];
[saveBarButtonItem setTarget:self];
[saveBarButtonItem setAction:#selector(savePhoto:)];
CGRect colorFrame = CGRectMake(0, 0, changeColorImage.size.width-25, changeColorImage.size.height-25);
UIButton* colorButton = [[UIButton alloc] initWithFrame:colorFrame];
[colorButton setBackgroundImage:changeColorImage forState:UIControlStateNormal];
[colorButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem* colorBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:colorButton];
[colorBarButtonItem setTarget:self];
[colorBarButtonItem setAction:#selector(chooseColor:)];
// add all the items
[toolbarItems addObject:cancelBarButtonItem];
[toolbarItems addObject:saveBarButtonItem];
[toolbarItems addObject:colorBarButtonItem];
[self.editBar setItems:toolbarItems animated:NO];
// release everything
[cancelBarButtonItem release];
[cancelButton release];
[saveBarButtonItem release];
[saveButton release];
[colorBarButtonItem release];
[colorButton release];
}
- (IBAction)cancelEdit:(id)sender {
NSLog(#"Pressing the cancel button");
}
- (IBAction)savePhoto:(id)sender {
NSLog(#"Pressing the save button");
}
- (IBAction)chooseColor:(id)sender {
NSLog(#"Pressing the choose color button");
}

So, here's the answer.
I was inserting a custom subview that was the size of the entire screen (320x640). It also had gestureRecognizers attached to it. Therefore, whenever I tapped that view, the gestureRecognizer responded to the attached subview, instead of the uitoolbar, or the buttons on it. Man I'm foolish. Resized the image on the UIView, and everything works fine. :) Thanks everyone for the help.

initWithCustomView - view must be button and set action on button

Related

Create new UI elements programmatically

I'd like to be able to create elements (like UIViews) when for example the user touches a button
NSMutableString *myVar = [NSMutableString stringWithFormat:#"_view%i", num];
UIView * newView = [self valueForKey:myVar];
but without adding all the
UIView * _view1;
UIView * _view2;
...
in the .h file (if only this is possible..)
You can use an NSMutableArray to hold them. Each time you create a new view just add it to the array.
Here's sample code that should do what you want.
#interface MyViewController ()
#property (strong, nonatomic) NSMutableArray *listChildViews;
#end
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.listChildViews = [[NSMutableArray alloc] init];
}
- (IBAction)addChildViewTapped:(id)sender
{
int numChildViews = [self.listChildViews count];
++numChildViews;
// add new child view
NSString *labelForNewView = [NSString stringWithFormat:#"view %d", numChildViews];
CGFloat labelHeight = 28.0;
UILabel *childView = [[UILabel alloc] initWithFrame:CGRectMake(10, numChildViews*labelHeight, 120.0, labelHeight)];
childView.text = labelForNewView;
[self.listChildViews addObject:childView];
[self.view addSubview:childView];
}
#end
Here is code implementation of pauls answer:
- (IBAction)userTouchedButton:(id)sender{
for (int i = 0; i < 100; i++) {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, y, width, height)];
[view setBackgroundColor:[UIColor redColor]];//to distinguish theseViews from other views
[view setTag:i];//to identified it later
[_array insertObject:view atIndex:i];// globleMutble array
[self.view addSubview:view];
}
}
You need not add your views in the .h file. Just instantiate before and where you add them
-(void) addButton
{
UIView *view = [self view];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button1 setTitle:#"My Button" forState:UIControlStateNormal];
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 0, 0)];
[myLabel setText:#"My Label"];
[button1 sizeToFit];
[myLabel sizeToFit];
[view addSubview:button1];
[view addSubview:myLabel];
}

UITextField keyboard can't type anything

load a xib file as a UIView, and I got a UITextField form a Xib file(it just a view that contains textfield and button).
But when the app launched and that textfield comes up. i cannot type any alphabet on this UITextField.
But paste a text to that UITextField was OK. Why?
Here is my adding code
-(IBAction)showSheet{
UIView *myView = [[[NSBundle mainBundle] loadNibNamed:#"LoginViewComp" owner:self options:NULL] lastObject];
[myView setFrame:CGRectMake(0, 44, 320, 400)];
UIButton *btn1 = (UIButton *)[myView viewWithTag:101];
UITextField *field = (UITextField *)[myView viewWithTag:102];
UILabel *lbl = (UILabel *)[myView viewWithTag:103];
[field setEnabled:YES];
[btn1 addTarget:self action:#selector(testBtn1) forControlEvents:UIControlEventTouchUpInside];
DTActionSheet *sheet = [[DTActionSheet alloc] initWithContentView:myView sheetTitle:#"Demo"];
[sheet showInView:self.view];
[sheet setUserInteractionEnabled:YES];
}
-(void)testBtn1{
NSLog(#"btn1 touch up inside");
}
#end
DTActionSheet.m
#interface DTActionSheet()
#property (nonatomic,strong) UIView* contentView;
#property (nonatomic,strong) UIToolbar* toolBar;
#end
#implementation DTActionSheet
#synthesize contentView=_contentView;
#synthesize toolBar=_toolBar;
-(id)initWithContentView:(UIView*)contentView sheetTitle:(NSString*)title;
{
self = [super init];
if (self)
{
_contentView = contentView;
int btnnum = (contentView.frame.size.height-5)/50; // (height+44-20-25)/50
for(int i=0; i<btnnum; i++)
{
[self addButtonWithTitle:#" "];
}
_toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
_toolBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *titleButton = [[UIBarButtonItem alloc] initWithTitle:title
style:UIBarButtonItemStylePlain
target:nil
action:nil];
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone
target:self
action:#selector(done)];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(cancel)];
UIBarButtonItem *fixedButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
[_toolBar setItems: [NSArray arrayWithObjects:leftButton,fixedButton,titleButton,fixedButton,rightButton,nil]];
[self addSubview:_toolBar];
[self addSubview:_contentView];
}
return self;
}
-(void)done
{
[self dismissWithClickedButtonIndex:0 animated:YES];
}
-(void)cancel
{
[self dismissWithClickedButtonIndex:0 animated:YES];
}
#end
Hey, guys, have any idea?
try using UIKeyInput Protocol Reference for input --
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIKeyInput_Protocol/Reference/Reference.html
make sure to use its delegate..

Creating a Label via a method in a class

I am slowly developing a custom button (while learning how to implement classes etc).
I have a ViewController, which imports a SuperButton.h (UIControl) and then creates an instance of the SuperButton. (This works, as proved by a NSLog.)
But I cannot get the method in SuperButton to display a Label.
I think this might have something to with the '.center' value or the 'addSubview' command?
I would really appreciate your help. Thanks.
Here is my SuperButton.m code:
#import "SuperButton.h"
#implementation SuperButton
#synthesize firstTitle;
#synthesize myLabel;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (void) shoutName{
NSLog(#"My name is %#", firstTitle);
self.backgroundColor = [UIColor blueColor];
CGRect labelFrame = CGRectMake(0.0f, 0.0f, 100.0f, 50.0f);
self.myLabel = [[UILabel alloc] initWithFrame:labelFrame];
self.myLabel.text = #"Come on, don't be shy.";
self.myLabel.font = [UIFont italicSystemFontOfSize:14.0f];
self.myLabel.textColor = [UIColor grayColor];
self.myLabel.center = self.center;
[self addSubview:self.myLabel];
}
Here is the code in my ViewController:
- (void) makeButton{
SuperButton *button1 = [[SuperButton alloc] init];
button1.firstTitle = #"Mr. Ploppy";
[button1 shoutName];
}
(EDIT:) Just in case, here's the SuperButton.h code:
#import <UIKit/UIKit.h>
#interface SuperButton : UIControl
#property (nonatomic, strong) NSString *firstTitle;
#property (nonatomic, strong) UILabel *myLabel;
- (void) shoutName;
#end
I found an answer elsewhere.
I needed to addSubview the 'button'. My working code now looks like this:
- (void) makeButton{
SuperButton *button1 = [[SuperButton alloc] init];
button1.firstTitle = #"Mr. Ploppy";
[button1 shoutName];
[self.view addSubview:button1.myLabel];
[self.view sendSubviewToBack:button1.myLabel];
}
You are initializing your button not with initWithFrame: method, but with simple init. This makes the button of CGRectZero size. Change this line:
SuperButton *button1 = [[SuperButton alloc] init];
to this:
SuperButton *button1 = [[SuperButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 50.0f)];
or add a call to setFrame: after initializing your button.

I want to perform different actions on tapping different Buttons created dynamically

Buttons are created dynamically and images are given to them through parsed urls, so i viewDidLoad i created them and released them in viewDidLoad only. So, when i click on Buttons i want to perform different tasks on click on different buttons. but i am not able to do it.
I tried to set Tag to them but again it is of no use as it is giving me EXC_BD_ACCESS.... any Help would be appreciated... :)
Code:-
#class AppDelegate_iPhone,Litofinter,ParsingViewController;
#interface FirstViewController : UIViewController<UIGestureRecognizerDelegate>{
NSMutableArray *array;
NSString *logoString;
AppDelegate_iPhone *appDelegate;
ParsingViewController *obj;
UIScrollView *scrollView;
NSMutableArray *idArray;
NSMutableArray * currentPdfUrl;
}
#property (nonatomic,retain)UIScrollView *scrollView;
//-(void)onTapImage:(UITapGestureRecognizer *)recognizer;
-(void)onTapButton:(id)sender;
#end
#import "FirstViewController.h"
#import "AppDelegate_iPhone.h"
#import "Litofinter.h"
#import "ParsingViewController.h"
#import "MyGesture.h"
#implementation FirstViewController
#synthesize scrollView;
-(id)init{
if(self == [super init]){
obj = [[ParsingViewController alloc] init];
array = [[NSArray alloc] initWithArray: obj.LogoMutableArray];
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
int x=20,y=10;
int a=50,b=105;
appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0,500, 460)];
scrollView.contentSize = CGSizeMake(320,800);
scrollView.showsVerticalScrollIndicator = YES;
for (Litofinter *lito in appDelegate.logoArray) {
NSString * urlString = [lito.cLogo stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSURL * imageURL = [NSURL URLWithString:urlString];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];
/*
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
[imgView setFrame:CGRectMake(x, y, 140, 90)];
imgView.userInteractionEnabled = YES;
imgView.multipleTouchEnabled = YES;
imgView.backgroundColor = [UIColor blueColor];
// imgView.tag = lito.cId;
// NSLog(#"Tag Id = %#",imgView.tag);
NSLog(#"Tag Id = %#",lito.cId);
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onTapImage:)];
tgr.delegate = self;
[imgView addGestureRecognizer:tgr];
[scrollView addSubview:imgView];
tgr.view.tag =(int)[NSString stringWithFormat:#"%#",lito.cId];
NSLog(#"Tag Id = %#",tgr.view.tag);
// NSLog(#"Tag Id = %#",lito.cId);
*/
UIButton *imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[imageButton setFrame:CGRectMake(x, y, 140, 90)];
[imageButton setImage:image forState:UIControlStateNormal];
[imageButton addTarget:self action:#selector(onTapButton:) forControlEvents:UIControlEventTouchUpInside];
[imageButton setTag:lito.cId];
[scrollView addSubview:imageButton];
UILabel *cName = [[UILabel alloc]initWithFrame:CGRectMake(a, b, 130, 20)];
cName.text = lito.cName;
[scrollView addSubview:cName];
//Do the rest of your operations here, don't forget to release the UIImageView
x = x + 150;
a = a + 140;
if(x >300)
{
y = y +140;
x = 20;
b = b +150;
a = 50;
}
//[tgr release];
// [imgView release];
}
[self.view addSubview:scrollView];
}
-(void)onTapButton:(id)sender
{
NSLog(#"Tag Id = %#",self.view.tag);
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Message from mAc" message:#"Tag Id" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok",nil];
[alert show];
}
You could change the selector depending on the button when setting the target
[imageButton addTarget:self action:#selector(onTapButton:) forControlEvents:UIControlEventTouchUpInside];
If you want to do it with tags, it could also work, your bad access is coming from
NSLog(#"Tag Id = %#",self.view.tag);
Which is assuming that tag is an NSObject (responding to the description selector), when in fact, it is a numeric value. Change it to:
NSLog(#"Tag Id = %i",self.view.tag);
Also, you want to be careful when using
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
as this is a synchronous API, it's ok if it's local files (although using [UIImage imageNamed:] is more economical as it caches the image data), it's really bad if it's network files (as it blocks the thread until the request ends, which could take ages).

Custom back button disappears after setting navigation bar background image

I'm using the following categories code to change
the background image of the navigation bar
#import <Foundation/Foundation.h>
#interface UINavigationBar (CustomImage)
- (void) setBackgroundImage:(UIImage*)image;
- (void) clearBackgroundImage;
#end
#import "UINavigationBar+CustomImage.h"
#implementation UINavigationBar (CustomImage)
- (void) setBackgroundImage:(UIImage*)image {
if (image == NULL) return;
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
[self insertSubview:imageView atIndex:0];
[imageView release];
}
- (void) clearBackgroundImage {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *mySubviews = [self subviews];
for (int i = [mySubviews count] - 1; i >= 0; i--)
{
if ([[mySubviews objectAtIndex:i] isMemberOfClass:[UIImageView class]])
{
[[mySubviews objectAtIndex:i] removeFromSuperview];
return;
}
}
[pool release];
}
#end
And i'm using the following code to generate the custom back button
in my view
UIButton *btnBack = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
[btnBack addTarget:self action:#selector(goBack) forControlEvents:UIControlEventTouchUpInside];
[btnBack setImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
UIBarButtonItem *barBtnBack = [[UIBarButtonItem alloc] initWithCustomView:btnBack];
self.navigationItem.leftBarButtonItem = barBtnBack;
[btnBack release];
[barBtnBack release];
But the button most of the time is hidden under the bg image
and some times it randomly appears.
Why is this happening? I'm not sure what's the problem the image is inserted at index 0
so as I understand it is supposed to be behind all the time.
Please help.
Try the following code to change background of the navigation bar in the class where you are loading the navigation bar.
#interface UINavigationBar (MyCustomNavBar)
#end
#implementation UINavigationBar (MyCustomNavBar)
- (void) drawRect:(CGRect)rect
{
UIImage *barImage = [UIImage imageNamed:#"image.png" ];
[barImage drawInRect:rect];
}
#end
Using the method Praveen S suggested you could have a global variable for the next background image name and set it in your viewDidLoad method, then in your draw rect method use the imageName stored in the variable rather than hardcoding it in the draw rect.
You should try creating the button after adding the image.