Action for dynamically created UIButton inside UITextView - iphone

I have a scroll view; inside I add one or more text views; to each text view I add a button:
UIScrollView
UITexView
UIButton
UITextView
UIButton
...
This is part of the code:
- (void)viewDidLoad {
...
[self loadUI];
...
}
-(void) loadUI {
UITextView *textView;
...
for (...) {
UIButton *editButton = [[UIButton alloc] initWithFrame:
CGRectMake(self.scrollView.frame.size.width - 230, 0, 50, 20)];
...
[editButton addTarget:self action:#selector(editPressed:)
forControlEvents:UIControlEventTouchUpInside];
...
textView = [[CustomTextView alloc] initWithFrame:
CGRectMake(10, dynamicHeight, self.queuedView.frame.size.width - 100, 500)];
textView.userInteractionEnabled = NO;
...
[textView addSubview:editButton];
[editButton release];
...
[self.scrollView addSubview:textView];
[textView release];
}
}
- (IBAction) editPressed:(id)sender {
...
}
For some reason, the editPressed method is not called when I press the button. Any ideas why? I tried setting the interaction enabled for the text view to YES, but still nothing. I changed form (IBAction) to (void), still nothing.
Thank you,
Mihai

Apparently, textView.userInteractionEnabled = YES; did the trick. I tried this before but it did not work. Maybe I had to do a clean build after the change.

Try adding the button to the rightView of the textfield
dotextField.rightView = editButton instead of [textView addSubview:editButton];

Related

UIAlertView Buttons(subviews) is not Showing in iOS 7

UIAlertView is working fine in ios 6 with below code .But when it comes to ios 7 the subviews ( "yes" and "no" buttons in my code ) is not showing when alertview is called only text message is showing .Can anyone tell me how to resolve this problem ?
viewController.m file
[Utilities prCustomAlert:#"Textmessage" inTitle:#"Alert view title" delegate:self inTag:300];
CustomAlertView *alertView = [Utilities sharedUtility].customAlertView;
alertView.numberOfBtns = 2;
UIButton *btn= (UIButton *)[alertView viewWithTag:10];
[btn setTitle:#"no" forState:UIControlStateNormal];
[btn addTarget:self action:#selector(dontlogout) forControlEvents:UIControlEventTouchDown];
btn = (UIButton *)[alertView viewWithTag:11];
[btn setTitle:#"yes" forState:UIControlStateNormal];
[btn addTarget:self action:#selector(logout) forControlEvents:UIControlEventTouchDown];
[Utilities displayCustomAlertForDelegate:self];
UIAlertView.m file
CGRect viewFrame = self.frame;
CGRect buttonFrame = button.frame;
if(self.numberOfBtns==2){
CGRect labelFrame = [self viewWithTag:15].frame;
button.frame = CGRectMake(10, 0, 40, 30);
button.hidden = NO;
//yes...
btn = (UIButton *)[self viewWithTag:11];
btn.frame = CGRectMake(60, 0, 40, 30);
btn.hidden = NO;
//no..
btn = (UIButton *)[self viewWithTag:10];
btn.hidden = YES;
}
We can add subviews to UIAlerView by adding subview to the presentedViewController's view when UIAlertView is presented. I have accessed UIAlertView like following way :
NSArray *subviews = [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.view.subviews;
I have created a subclass of UIAlerView :
Header File :
#interface MLKLoadingAlertView : UIAlertView
- (id)initWithTitle:(NSString *)title;
#end
Implementation File :
#import "MLKLoadingAlertView.h"
#define ACTIVITY_INDICATOR_CENTER CGPointMake(130, 90)
#implementation MLKLoadingAlertView
- (id)initWithTitle:(NSString *)title
{
if ( self = [super init] )
{
self.title = title;
self.message = #"\n\n";
[self setDelegate:self];
}
return self;
}
// You can Customise this based on your requirement by adding subviews.
- (void)didPresentAlertView:(UIAlertView *)alertView
{
NSArray *subviews = [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.view.subviews;
if( subviews.count > 1 )
{
// iOS while presenting an alertview uses a presening view controller. That controller's view has several subviews. I have picked one
// subview from it which has frame similar to the alertview frame.
UIView *presentedView = [subviews objectAtIndex:1];
UIActivityIndicatorView *customActivityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[customActivityIndicator startAnimating];
customActivityIndicator.center = ACTIVITY_INDICATOR_CENTER;
[presentedView addSubview:customActivityIndicator];
}
}
#end
In - (void)didPresentAlertView:(UIAlertView *)alertView method I have added the subviews to UIAlertView by accessing Presented View Controller's view.
You can find explanation and code example for this on Here
What you were doing was always wrong. You are not allowed to add your own subviews to a UIAlertView. The good news is - in iOS 7, you don't have to! The new custom transition animation mechanism lets you make your own view that behaves just an alert view, but since it is your view, you can put anything you like into it, like this:
Note how the fake "alert view" floats in front of the original view in the screen shot on the right, and dims the screen behind it, just like a real alert view. But it is made up entirely of custom content; a "real" alert view could never contain an image and a switch!
For the code that creates this view, which you can easily adapt to your own purposes, see my github site: https://github.com/mattneub/custom-alert-view-iOS7
I think the root of the problem in iOS7 that Apple changed the UIAlertView appearance mechanism.
From now any show of alertView follows after initiating of two private view controllers
_UIModalItemAppViewController
_UIModalItemsPresentingViewController
In other words, now UIAlertView is not a pure view - it is a part of some complicated collection of view controllers with full view controller life cycle.
But a good news that you can change accessoryView to your customContentView in a standard alert view
[alertView setValue:customContentView forKey:#"accessoryView"];
Note that you must call this before [alertView show].

Programmatically created button not firing event in custom view in iOS

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..

adding a UILabel as subview of UIButton doesn't trigger button action

I have a UIButton and I am adding a subview to the UIButton which is a UILabel. When I tap on the UILabel the action of the button doesn't get triggered. Is there an easy fix so that the touch event gets passed to the UIButton when the UILabel is tapped?
I am thinking of adding a gesture recognizer to the UILabel which then triggers the action of the UIButton, not sure if there's a much more simpler way.
You can probably just disable user interaction to your label.
_yourLabel.userInteractionEnabled = NO;
try this,
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *firstButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[firstButton setTitle:#"first" forState:UIControlStateNormal];
firstButton.frame=CGRectMake(40, 70, 80, 80);
[firstButton addTarget:self action:#selector(firstButtonClicked) forControlEvents: UIControlEventTouchUpInside];
[self.view addSubview:firstButton];
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 80, 80)];
label.text=#"hai";
label.backgroundColor=[UIColor redColor];
[firstButton addSubview:label];
}
-(void)firstButtonClicked {
NSLog(#"first");
}

number pad keyboard not show return key in iphone

I am new to iPhone technology. I've saved a problem in a iPhone application, but when i use textfield keyboard type number pad the keyboard doesn't show a return/done button.
How can I hide the number pad keyboard after entering the number in the textfield? Do you have any solutions for that. Please provide help.
You can do this in this way:
#property (nonatomic, strong) UITextField *textField;
- (void)viewDidLoad {
[super viewDidLoad];
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonDidPressed:)];
UIBarButtonItem *flexableItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL];
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[self class] toobarHeight])];
[toolbar setItems:[NSArray arrayWithObjects:flexableItem,doneItem, nil]];
self.textField.inputAccessoryView = toolbar;
}
- (void)doneButtonDidPressed:(id)sender {
[self.textField resignFirstResponder];
}
+ (CGFloat)toolbarHeight {
// This method will handle the case that the height of toolbar may change in future iOS.
return 44.f;
}
you must be using UIKeyboardTypeNumberPad, try this instead UIKeyboardTypeNumbersAndPunctuation,
It'll not only show the return key but also provide you with some extra punctuations
There is no return or done key in number pad. You can do one thing when user touch outside of the textfield you can hide the keyboard. You should do something like this -
if (there is a touch outside of your textField)
{
[textField resignFirstResponder];
}
This question has already been answered, I know because thats how i got the solution. You have 2 options, first is to hide the keyboard by implementing a touch on the mainview that will send the "finished editing" message. that Hides the keyboard [self.view endEditing:YES];
If you do add the touch listener to the mainview you have to implement a condition so that any other buttons keep working.
What you do want to do to simulate a return key is to actually add it like this:
Register for a keyboard did show notification and add this to the code:
if ([self.passCodeLabel isFirstResponder])
{
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 163, 106, 53);
//doneButton.frame = CGRectMake(0, 163, 257, 257);
doneButton.adjustsImageWhenHighlighted = NO;
[doneButton setImage:[UIImage imageNamed:#"doneup.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:#"donedown.png"] forState:UIControlStateHighlighted];
[doneButton addTarget:self action:#selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];
// locate keyboard view
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
NSLog(#"%#",[[UIApplication sharedApplication] windows]);
UIView* keyboard;
NSLog(#"Shared applicaiton windows count:%i",tempWindow.subviews.count);
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
NSLog(#"%#",[keyboard description]);
// keyboard view found; add the custom button to it
if([[keyboard description] hasPrefix:#"<UIPeripheralHostView"] == YES)
{
NSLog(#"Adding return button");
[keyboard addSubview:doneButton];
}
}
}
This will add your own "done" button image to the keyboard (which you can just copy by taking a screenshot of the screen of the blank slot and adding the done text).
Btw the code i pasted works on my layout. For yours you might have to modify it a bit, but the principle is the same.
Create the button
Look for the keyboard subview
Add the button to that subview
- (void)viewDidLoad
{
[super viewDidLoad];
UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
numberToolbar.barStyle = UIBarStyleBlackTranslucent;
numberToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneWithNumberPad)],
nil];
[numberToolbar sizeToFit];
_txt_mobileno.inputAccessoryView = numberToolbar;
}
-(void)doneWithNumberPad
{
[_txt_mobileno resignFirstResponder];
}

Show UIButton when Image is touched?

is there any way to hide an UIButton until the UIImageView is pressed??
When the picture is pressed I need to show the back Button, like it works at the Photo App on the iPhone???
Here is the code of my UIButton:
- (void)viewDidLoad {
[super viewDidLoad];
[self ladeImage];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(10, 10, 40, 40);
[btn addTarget:self action:#selector(goToViewA) forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:#"<<" forState:UIControlStateNormal];
[self.view addSubview:btn];
}
First step : btn.hidden = YES
Then you have to subclass the UIImageView to react to its touchesEnded: event and change the hidden property of your button there. For that, the proper way is to create a protocol (with a viewTouched method). Implement that protocol in the viewController containing your button and you ImageView. Add a delegate propery to the subclassed ImageView (i.e. id<MyCustomProtocol> _delagate;) and assign the view controller to this propery.
btn.hidden = YES;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image name"]];
imageView.userInteractionEnabled = YES; // here to enable touch event
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGestureRecongizer:)]; // handleTapGestureRecongizer is method will call when tap even fire
[imageView addGestureRecognizer:tap]; // Add Tap gesture recognizer to image view
[tap release], tap = nil;
[self.view addSubview:imageView];
[imageView release], imageView = nil;
Method handlerTapGestureRecognizer:
- (void)handleTapGestureRecongizer:(UITapGestureRecognizer *)gestureRecognizer{
if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
btn.hidden = NO;
}
}
have fun!