I am trying to block any touch event on UITTextField. To do so, I am trying to place a UIView/Button/Label on top of UITexfield.
But on simulator, I can still click at any location inside text field. What is wrong with my code? How can I put UIButton/Lable on top of textfield so that user can not click anywhere inside text field.
Please note I still want Number Keyboard input in the textfield. I just want to disable clicks/cut/copy/paste/select etc.
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 292, 50, 40)];
[self.textField becomeFirstResponder];
[self.textField setKeyboardType:UIKeyboardTypeNumberPad];
self.textField.delegate = self;
[self.view addSubview:self.textField];
UIButton *topViewonTextField = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight)];
topViewonTextField.backgroundColor = [UIColor clearColor];
[topViewonTextField setEnabled:NO];
//topViewonTextField.layer.zPosition = 100;
[self.view addSubview:topViewonTextField];
#define MAIN_SCREEN [UIScreen mainScreen]
#define ScreenWidth [MAIN_SCREEN bounds].size.width
#define ScreenHeight [MAIN_SCREEN bounds].size.height
If you want "block" a textField, tell to it:
texField.userInteractionEnabled = NO;
Big explanations:
// You create your textField, It can't receive events. By code or in Story
self.textField= [[UITextField alloc] initWithFrame:CGRectMake(10, 190, 80, 30)];
self.textField.placeholder = #"hola";
self.textField.userInteractionEnabled = NO;
self.textField.delegate = self;
[self.view addSubview:self.textField];
//Some Button or other event make the textField in editing mode.
UIButton *buttonToEdit = [[UIButton alloc] initWithFrame:CGRectMake(250, 250, 80, 80)];
[buttonToEdit setTitle:#"ActionToEdit" forState:UIControlStateNormal];
[buttonToEdit addTarget:self action:#selector(editMyTextField) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:buttonToEdit];
}
-(void)editMyTextField
{
self.textField.userInteractionEnabled = YES;
[self.textField becomeFirstResponder];
}
// The las step (to you) is in the delegate, when the editing finish, go back to no interaction
#pragma mark - TextFieldDelegate
-(void)textFieldDidEndEditing:(UITextField *)textField
{
if ([textField isEqual:self.textField]) {
self.textField.userInteractionEnabled = NO;
// more code here, validate...
}
}
Check this: How to disable paste option in menucontroller in iOS?
Related
I want to create a bottom tab that could change the view when user press.
To do that I create a view with view controller and sets it's frame in the init
Here is the bottom panel view controller
#implementation BottomTabViewController
-(id) initWithFrame:(CGRect)frame{
if(self = [super init]){
self.view.frame = frame;
return self;
}else{
return nil;
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpButtons];
// Do any additional setup after loading the view.
}
-(void) featureBtnClick:(id*) sender{
NSLog(#"featureBtn Clicked");
}
-(void) favBtnClick:(id*)sender{
NSLog(#"Fav Btn Clicked");
}
-(void) setUpButtons{
UIButton *features = [[UIButton alloc]initWithFrame:CGRectMake(10, 10, 50, 50)];
[features setBackgroundImage:[UIImage imageNamed:#"feature.png"] forState:UIControlStateNormal];
features.backgroundColor = [UIColor greenColor];
[features addTarget:self action:#selector(featureBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:features];
UIButton *favBtn = [[UIButton alloc]initWithFrame:CGRectMake([[UIScreen mainScreen]bounds].size.width - 100, 10, 50, 50)];
[favBtn setBackgroundImage:[UIImage imageNamed:#"favorite.png"] forState:UIControlStateNormal];
[favBtn addTarget:self action:#selector(favBtnClick:) forControlEvents:UIControlEventTouchUpInside];
favBtn.backgroundColor = [UIColor greenColor];
[self.view addSubview:favBtn];
}
#end
And I added that to my view with code like this:
-(void) setUpBottom{
BottomTabViewController *botm = [[BottomTabViewController alloc]initWithFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 55, [[UIScreen mainScreen]bounds].size.width, 55)];
botm.view.backgroundColor = [UIColor redColor];
// botm.view.userInteractionEnabled = false;
botm.view.userInteractionEnabled = true;
[self.view addSubview:botm.view];
}
Here here is the result seems, note the bottom panel that works, well pretty silly, but it shows up:
But when press the left and right button, there is not log printed which it expected to be to indict that the button works, What have I done wrong? Thanks
you are adding buttons in the view first then adding the bottom view.
if this is what you are doing then it can be overlapped by the bottom view.
In this case buttons cant be tapped because they have bottom view on top of them.
so make sure u add bottom view first then your buttons. (or change their frames to avoid overlapping)
Have added a custom view consisting of buttons on top of the keyboard. The buttons are being displayed correctly but on tapping on the buttons, the underlying keys of the keyboard are pressed instead of the button actions.
UIWindow* tempWindow = [UIApplication sharedApplication].windows.lastObject;
for (UIView *keyboard in [tempWindow subviews]) {
if ([[keyboard description] hasPrefix : #"<UIInputSetContainerView"]) {
for(int i = 0 ; i < [keyboard.subviews count] ; i++)
{
UIView* hostkeyboard = [keyboard.subviews objectAtIndex:i];
if([[hostkeyboard description] hasPrefix:#"<UIInputSetHost"] == YES){
[hostkeyboard addSubview:extraRow];
[hostkeyboard bringSubviewToFront:extraRow];
}
}
}
}
extraRow is the UIView consisting of buttons.
Is there anything missing ?
You could do just add a custom view to the keyboard as an inputAccessoryView. Then it just assign the button the correct target you want it to fire when clicked on
- (void)textFieldDidBeginEditing:(UITextField *)textField {
UIView * theView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];
[theView setBackgroundColor: [UIColor greyColor]];
UITextField * txtTest = [[UITextField alloc] initWithFrame:CGRectMake(0, 5, theView.frame.size.width, 60)];
UIButton * btn = [[UIButton alloc] initWithFrame:CGRectMake(20, 65, 100, 30)];
[btn setTitle:#"Click my Button" forState:UIControlStateNormal];
[btn addTarget:self action:#selector(alert:) forControlEvents:UIControlEventTouchUpInside];
// Just put this to see the items or customize the color
[txtTest setBackgroundColor:[UIColor whiteColor]];
[btn setBackgroundColor:[UIColor blueColor]];
// Need this to add it to the view
[theView addSubview:txtTest];
[theView addSubview:btn];
textField.inputAccessoryView = theView;
}
One thing you might want to consider is setting the extraRow's exclusiveTouch property to YES. As a disclaimer I haven't tried this example myself but I think the problem you are having is due to the view passing along the touch event.
I have a UITextView and i want to disable it's 'editable' property if the state of the UISwitch is set to ON.
myTextView = [[UITextView alloc]initWithFrame:CGRectMake(20, 180, 200, 30)];
myTextView.backgroundColor = [UIColor whiteColor];
myTextView.text = #"This is a textView";
[self.view addSubview:myTextView];
mySwitch = [[UISwitch alloc]initWithFrame:CGRectMake(230, 125, 200, 30)];
[self.view addSubview:mySwitch];
I know that i can check the state of a switch using:
if ([mySwitch isOn]) {
myTextView.editable = NO;
} else {
myTextView.editable = YES;
}
The problem is when i run my project the text is not editable, but when i slide the switch the text cannot be edited (which is obvious with above code). I want to know what do i have to do to change the editable property of the UITextView, if i toggle the switch.
UISwitch is a subclass of the UIControl class, which among other things, provides a target-action-based model for receiving updates about the state of the control.
This means that you can use the -[UIControl addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents] method to have your method called when the switch changes its boolean value:
[yourSwitch addTarget:self action:#selector(switchToggled:) forControlEvents:UIControlEventValueChanged]
You can also do this from Interface Builder, by right-clicking on your UISwitch and assigning its action to the appropriate IBAction method:
- (IBAction) switchToggled:(UISwitch*)switchControl {
yourTextView.editable = switchControl.on;
}
You need to add an IBAction and hook it up to the switch method Value Changed
-(IBAction)toggleSwitch:(UISwitch*)sw {
myTextView.editable = sw.on;
NSLog(#"Value Changed");
}
Edit: Code for doing it programmatically rather than via Interface Builder
myTextView = [[UITextView alloc]initWithFrame:CGRectMake(20, 180, 200, 30)];
myTextView.backgroundColor = [UIColor whiteColor];
myTextView.editable = NO;
myTextView.text = #"This is a textView";
[self.view addSubview:myTextView];
mySwitch = [[UISwitch alloc]initWithFrame:CGRectMake(230, 125, 200, 30)];
mySwitch.on = NO;
[mySwitch addTarget:self action:#selector(toggleSwitch:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:mySwitch];
-(void)toggleSwitch:(UISwitch*)sw {
myTextView.editable = sw.on;
}
You have to create an action for the switch which fires when the switch's state has changed. If you are using storyboard, right-drag from the switch to the code (like to create an outlet) and choose action. Inside that function you check whether your switch is now on or off and according to that you make your TextView editable or not
if ([mySwitch isOn]) {
myTextView.editable = NO;
[myTextView resignFirstResponder];
} else {
myTextView.editable = YES;
[myTextView becomeFirstResponder];
}
I am programmatically creating buttons in a view inside UIScrollView. I also have programmatically created UITextField. I can select and enter data into the text fields all day long. But I cannot get any sign the buttons are being touched. I can add them to the main view and they work. But when added to the view inside the UIScrollView, they are lost in another dimension. I've read plenty of info about setting userInteraction, delayContentTouches, and intercepting via gestureRecognizer. The last might be related to my problem. I return NO via [touch.view isDescendantOfView:self.myScrollViewName]. I can't get it to trigger via [touch.view isKindOfClass:[UIButton class]]. Which makes me think I have a more fundamental error I am missing?
related:
https://stackoverflow.com/a/6825839/4050489
edited to add button code per request:
self.myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.myButton.frame = myButtonFrame;
self.myButton.enabled = interface.isActive;
self.myButton.userInteractionEnabled = YES;
self.myButton.exclusiveTouch = YES;
self.myButton.backgroundColor = [UIColor greenColor];
//self.myButton. = YES;
self.myButton.layer.borderWidth=1.0f;
self.myButton.layer.borderColor=[[UIColor blackColor] CGColor];
self.myButton.layer.cornerRadius = 10;
[self.myButton setTag:interface.tag];
[self.myButton setTitle:interface.Name forState:UIControlStateNormal];
[self.myButton addTarget:self action:#selector(navigatePartButtons:) forControlEvents:UIControlEventTouchUpInside];
[self.myButton setEnabled:YES]; //error check
[self.partSetupView addSubview:self.myButton];
partSetupView is a UIView in the UIScrollView.
Try this sample Code:
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIScrollView *myScroll = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 100, 300, 300)];
myScroll.backgroundColor = [UIColor redColor];
[self.view addSubview:myScroll];
UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 300, 200)];
myView.backgroundColor = [UIColor yellowColor];
[myScroll addSubview:myView];
UIButton *myButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 300, 100)];
myButton.backgroundColor = [UIColor blackColor];
[myView addSubview:myButton];
[myButton addTarget:self action:#selector(btnClick) forControlEvents:UIControlEventTouchDown];
}
-(void)btnClick{
NSLog(#"Button Click");
}
#end
I'm having trouble implementing a UISearchBar whose UITextField has a rightview. I tried on a normal UITextField the following:
self.textField = [[UITextField alloc] initWithFrame: CGRectMake(10, 30, 300, 30)];
self.textField.borderStyle = UITextBorderStyleRoundedRect;
self.textField.clearButtonMode = UITextFieldViewModeNever;
self.textField.delegate = self;
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, 150, 44)];
[button setBackgroundColor: [UIColor redColor]];
[self.textField setRightViewMode:UITextFieldViewModeAlways];
[self.textField setRightView:button];
[self.view addSubview:self.textField];
And as expected, it generates the following:
I need the UISearchBar's UITextField to be have the same -- so I decided to subclass UISearchBar.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// This is simply here to make sure that we are able to get the textfield
[self setSearchTextPositionAdjustment:UIOffsetMake(0, 0)];
// Function that helps us get the textfield
UITextField *textField = [self textFieldGetter];
// This will be true if we call setSearchTextFieldPositionAdjust
if (textField) {
// Verify that the textfield exists...
NSLog(#"The textField does exist");
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, 150, 44)];
[button setBackgroundColor: [UIColor redColor]];
// Set the clear button to be off
textField.clearButtonMode = UITextFieldViewModeNever;
// Make the button the rightview of the textfield
[textField setRightView:button];
[textField setRightViewMode:UITextFieldViewModeAlways];
}
}
return self;
}
But it does not work and the UISearchBar simply looks like:
The UITextFieldGetter is in essence something very similar to this answer.
Why isn't the UITextField the same in the UISearchBar as it is normally? Is there a way that I can get the same effect programmatically? Or if it can't be done, is there a way that I can change the UITextField's width once I know the button is there?