Programmatically created button not firing event in custom view in iOS - iphone

On iOS, I created a button programmatically but the event is not firing.
UIButton * anyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[anyButton addTarget:self action:#selector(handleAnyButton:) forControlEvents:UIControlEventTouchUpInside];
anyButton.frame = CGRectMake(150, 350, 22, 22);
[self addSubview:anyButton];
The code is placed inside a custom view (not custom view controller), but I cannot make it fire the event. The press animation is not showing. The custom view has userInteractionEnabled enabled. I also tried using storyboard to create another button on the same view and that one is working. The button code is done in initWithFrame. Must be some simple error I haven't caught and I have been pounding my head over this one for hours.
EDIT:
The event handler:
-(void) handleAnyButton:(UIButton *)button
{
NSLog(#"handleAnybutton called");
}
EDIT2:
The above button codes is done within a [self setup] of class PKLocationsSelectionView.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setup];
}
return self;
}
And this view was created programmatically within the view controller (PKLocSelectionViewController) responsible for this hierarchy:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
CGFloat fieldsHeight = 88;
UIView * view = [[PKLocationsSelectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, fieldsHeight)];
[self.view addSubview:view];
}

It looks like your button frame
anyButton.frame = CGRectMake(150, 350, 22, 22);
is outside of parent bounds
CGFloat fieldsHeight = 88;
UIView * view = [[PKLocationsSelectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, fieldsHeight)];

Here is the code that works for me:
MyCustomView.m:
#import "MyCustomView.h"
#implementation MyCustomView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 100, 100);
[button addTarget:self action:#selector(greet:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Greet" forState:UIControlStateNormal];
[self addSubview:button];
self.backgroundColor = [UIColor greenColor];
}
return self;
}
-(void) greet:(id) sender
{
NSLog(#"greet!");
}
And here is the ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
MyCustomView *view = [[MyCustomView alloc] init];
view.frame = CGRectMake(0, 0, 100, 100);
[self.view addSubview:view];
}

EDIT2: Could it be the Button is not fully enclosed within the coordinates of the container (PKLocationsSelectionView) view?
The height of the PKLocationsSelectionView is 88 from your code and the position of the button seems to be outside this. I think if the button is not enclosed within the frame of the superview then it won't receive touches.

Try and change your View initialization code in viewDidLoad, to give a static frame and see if it works..
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
CGFloat fieldsHeight = 88;
//See the change in below line.. instead of using self.view.bounds.size.width
// I used a static width.. 320 pixel for the moment..
UIView * view = [[PKLocationsSelectionView alloc] initWithFrame:CGRectMake(0, 0, 320.0, fieldsHeight)];
[self.view addSubview:view];
}
In viewDidLoad view hierarchy of controller will not be drawn completely..So self.view.bounds.size.width may be giving incorrect values.. To access self.view.frame and self.view.bounds, you should atleast wait until viewWillAppear gets called.
Also, your button origin.y is at 350 which in a view which has maximum height of only 88.. Any control outside parent's frame won't receive touches..

Related

How can I create an array of UIButtons/(UIImageViews) that appear after the last one was pressed

I wasn't sure how to search for the answer to this question so I figured I would try my luck over here.
To put this in short, I have a UIView and created a UIButton programmatically along with a UIImageView added to the button as a subview and what happens is, when I press on the button, it allows me to add an image and it gets stored over the button.
So my question is: Once that is completed, how can I make it that another button/ImageView will appear in the view, next to the first button (or after it fills the screen to the right, appear in the 2nd row, 1st column) etc
Thank you in advanced!
You can use UICollectionView as pointed out by #Bernahard Harrer or you could use the following code. This code adds only two buttons. In case, you need more buttons or an array of buttons, implement the following code and calculate the size of the previously added button, as height/width of button1 is calculated for adding button2:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self addButtons];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) addButtons
{
UIView *view = [self view];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button1 setBackgroundImage:[UIImage imageNamed:#"buttonImage1"] forState:UIControlStateNormal];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button2 setBackgroundImage:[UIImage imageNamed:#"buttonImage2"] forState:UIControlStateNormal];
[button1 sizeToFit];
[button2 sizeToFit];
CGFloat combinedWidth = (button1.frame.size.width) + (button2.frame.size.width) ;
//checking if combined width of both buttons is more than 320
if (combinedWidth>320) {
CGFloat button1height = button1.frame.size.height;
button1height = button1height + 10;
[button2 setFrame:CGRectMake(button2.frame.origin.x, (button2.frame.origin.y + button1height), button2.frame.size.width, button2.frame.size.width)];
} else {
//if combined width of both buttons is less than or equal to 320
//this will place the buttons adjacent to each other.
//The code may be modified accordingly if to add some distance between them
CGFloat button1width = button1.frame.size.width;
[button2 setFrame:CGRectMake((button1.frame.origin.x+button1width), button2.frame.origin.y, button2.frame.size.width, button2.frame.size.height)];
}
[view addSubview:button1];
[view addSubview:button2];
}#end
You can try to use a UICollectionView for this issue.
#interface ViewController (){
NSInteger x;
NSInteger y;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
x = 4;y=100;
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)addViews:(id)sender {
CGRect frame = CGRectMake(x, y, 40, 10);
int offset = 30;
x = (frame.origin.x + frame.size.width + offset);
UIView *view = [[UIView alloc] initWithFrame:frame];
[view setBackgroundColor:[UIColor redColor]];
if (view.center.x+view.frame.size.width > 320) {
y +=20;
x = 4;
}
[view setFrame:frame];
[self.view addSubview:view];
}
#end

Button hidden behind my BaseViewController in iPhone

I am facing weird problem. I have a baseViewController which extends with UIViewController.
in My BaseView controller i have a custom HeaderBar (UIImageView) on top of it.
I then made a new ViewController and extends that new ViewController with baseViewController. The headerBar in BaseViewController is appearing on my UIViewController. But now if I add any subview in my NEWViewController over that headerBar then it does not come over that whereas it goes behind the header bar.
Can anybody suggest what to do.
EDITED
Here is my code.
BASEViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
CGFloat xOffset = 0;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
xOffset = 224;
}
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
headerBarView = [self addHeaderBar];
//[self.view addSubview:headerBarView];
[self.view insertSubview:headerBarView belowSubview:self.view];
}
return self;
}
-(UIView *)addHeaderBar{
UIView *header_bar = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320, 50.0)];
//HeaderBar Image
UIImageView *headerBar = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0.0, 320, 50.0)];
[headerBar setImage:[UIImage imageNamed:#"top_bar"]];
[header_bar addSubview:headerBar];
return header_bar;
}
NEWViewController Extended With BaseViewController
//Back Button
back = [UI getActionBarButtonWithName:[NSString stringWithFormat:#"Back"] andCGRect:CGRectMake(7.0, 100.0, 55.0, 31.0) andEdgeInset:UIEdgeInsetsMake(0.0, 9.0, 2.0, 0.0) withBackGround:[UIImage imageNamed:#"back_button"]];
[self.view bringSubviewToFront:back];
+(UIButton *)getActionBarButtonWithName:(NSString *)name andCGRect:(CGRect)rect andEdgeInset:(UIEdgeInsets)edgeInset withBackGround:(UIImage *)background{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = rect;
[button setBackgroundImage:background forState:UIControlStateNormal];
[button setTitleEdgeInsets:edgeInset];
[button setTitle:name forState:UIControlStateNormal];
[button.titleLabel setFont:[UIFont boldSystemFontOfSize:13.0]];
[button setUserInteractionEnabled:YES];
return button;
}
if you are having many views, you can also use any one of these -
[self.view insertSubview:<#(UIView *)#> aboveSubview:<#(UIView *)#>]
[self.view insertSubview:<#(UIView *)#> atIndex:<#(NSInteger)#>]
[self.view insertSubview:<#(UIView *)#> belowSubview:<#(UIView *)#>]
hope it will help you.
Try using
[self.view bringSubviewToFront:button];
New UIVIew override your base viewcontroller,you can set frame of new view and then add subview.
Ex. UIView* tempView=[UIView alloc]initWithFrame:CGRectMake(0,44,320,420)];
[self.view addSubView:temView];

iphone viewForZoomingInScrollView not called

Edit: I have controller containing uiscrollview. That scrollview contains custom uiview having its separate class inherited from uiview. That uiview has uiimageview as subview. No i am taking "(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView" in main controller. But that method didn't get fire when i zoom scrollview. What should i do so that this method may get called.
UIView *DrawingPlusImageView = [[UIView alloc]initWithFrame:CGRectMake((i*IMAGEVIEW_IPAD_LAND_X+112), 0, 800, 600)];
IDDrawingView *drawView = [[IDDrawingView alloc]initWithFrame:CGRectMake(0, 0, 800, 600)];
UIImageView* imgViewLand = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)];
[imgViewLand setImage:[UIImage imageNamed:#"noFileSelected.png"]];
[drawView setImageToDraw:imgViewLand.image];
// drawView.delegate = self;
[drawView setCurrentSlidId:hmslide.strSlideID];
[DrawingPlusImageView addSubview:imgViewLand];
[DrawingPlusImageView addSubview:drawView];
[scrollViewPresentation addSubview:DrawingPlusImageView];
drawView.userInteractionEnabled = YES;
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
// Return the view that we want to zoom
return [self.scrollViewPresentation.subviews objectAtIndex:1];// there are slides, im zooming the second
}
I was having the same problem. and setting the minimum and maximum zoom levels for ScrollView solved my problem..try
self. scrollViewPresentation.minimumZoomScale = 1.0;
self. scrollViewPresentation.maximumZoomScale = 10.0;
It's only called once you begin to zoom. The view should be a subview of the scrollview, keep a reference to it as a property and return that in the delegate method:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:self.scrollView];
[self.scrollView addSubview:self.container];
[self.container addSubview:self.imageView];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}

Size of UIPickerView is not set correctly

I need to show a view that is not full screen and has a button and pickerView under it.
I tried using this code:
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(20,20,200,200)];
container.backgroundColor=[UIColor whiteColor];
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y+5, 170, 20); // position in the parent view and set the size of the button
myButton.titleLabel.textColor=[UIColor redColor];
myButton.titleLabel.text=#"click me";
//myButton.backgroundColor=[UIColor blueColor];
//[myButton backgroundImageForState:<#(UIControlState)#>[UIImage imageNamed:#"iPhone_mainbutton_green.png"];
// add targets and actions
[myButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
// add a buttonview
[container addSubview:myButton];
UIPickerView *piker=[[UIPickerView alloc] initWithFrame:CGRectMake(container.frame.origin.x, container.frame.origin.y +30, 100, 100)];
//piker.numberOfComponents=1;
piker.showsSelectionIndicator=YES;
//piker.delegate=self;
//piker.dataSource=self;
[container addSubview:piker];
[myButton release];
[piker release];
[self.view addSubview:container];
and i get this (picker out of the screen and very large, not 100x100):
you are adding you pickeer view in container and container frame is:-(20,20,200,200)
make it(0,20,200,200).
You are adding your UIPickerView as subview of "container"
UIPickerView *piker=[[UIPickerView alloc] initWithFrame:CGRectMake(container.frame.origin.x, container.frame.origin.y +30, 100, 100)];
this means pickerview takes its origin from container not from UIView if you want it to on right position do this :-
UIPickerView *piker=[[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100, 100)];
[container addSubview:picker];
just focus on your origin and remember every subview takes it origin from its parent view.
and One more thing apple doesn't allow to change pickerview Height so you cant set it 100x100 you can just change of its width. UIPickerView supports only 3 height value and these are 216.0 , 180.0, 162.0 try to set height only from these 3 value. it will be work.
let me know if you have any query regarding this.
If you want to adjust the frame, do it in your view controller's viewWillAppear: method - you can adjust it there.
Make sure that you also implement widthForComponent: and the width of all your components combined is less then the frame width - picker inset. I use the following:
- (void)viewDidLoad{
self.picker = [[[UIPickerView alloc] init] autorelease];
[self.view addSubview:self.picker];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.settingsPicker.frame = CGRectMake(0.0, 100.0, self.view.frame.size.width, 100.0);
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
CGFloat guessedPickerInsetWidth = 24;
CGFloat pickerWidth = self.view.frame.size.width - guessedPickerInsetWidth;
if (component == SettingsPickerFirstComponent) {
return pickerWidth * 0.4; // make the first component 40%
}
return pickerWidth * 0.3; // only two others, make them 30% each
}

Objective-C: addTarget:action:forControlEvent for subview button

I'm doing an iPhone ap which contains a viewController class (PhotoListViewController). This viewController's view has a subview which contains a button attached as a subview. I'm trying to use the addTarget:action:forControlEvent method to call an instance method of the PhotoListViewController class in order to perform an action when the button is pressed but the method is not being called. Any thoughts on how to make this work?
Here's the pertinent code. I know your first though will be why am I nesting subviews, but this just a distilled version of my program - there are reasons I'm doing the nesting. I know there are probably other ways of setting up the program so I don't have to do this nesting, but my real question is - why does this not work?
/Code/
#implementation PhotoListViewController
- (void)loadView {
[super viewDidLoad];
//load elements into the viewController
//first create the frame
CGRect frameParent = CGRectMake(0, 0, 0, 0);
UIView *viewPerson = [[UIView alloc] initWithFrame:frameParent];
CGRect frameChild = CGRectMake(0, 20, 0, 0);
UIView *newView = [[UIView alloc] initWithFrame:frameChild];
UIButton *btnShow = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btnShow.frame = CGRectMake(230, 120, 80, 30);
[btnShow setTitle:#"View!" forState:UIControlStateNormal ];
[btnShow addTarget:self
action:#selector(viewPhoto_click:)
forControlEvents:UIControlEventTouchUpInside];
[newView addSubview:btnShow];
[viewPerson addSubview:newView];
[newView release];
[self setView:viewPerson];
[viewPerson release];
}
- (void)viewPhoto_click:(UIButton*)sender {
NSLog(#"HI");
}
It may not be related, but both viewPerson and newView have a width and height of 0. You may want to give these views a non-null size (the 3rd and 4th arguments of CGRectMake).
action:#selector(viewPhoto_click:)
forControlEvents:UIControlEventTouchUpInside];
May be a copy paste typo but have you tried to remove the : after the viewPhoto_click after the selector?
Also. In most examples the event Handler look like this.
- (void) viewPhoto_click: (id)sender
Not sure if it makes any difference though