Is there a way to programmatically enable or disable the Return Key on the UIKeyboard
? The closest I could find is enablesReturnKeyAutomatically
, but that only will tell whether to disable it at all.

- 2,715
- 6
- 27
- 50

- 139,698
- 36
- 220
- 238
8 Answers
Maybe the following code segment helps:
textfield.enablesReturnKeyAutomatically = YES;
This is publicly available in iPhone SDK in UITextInputTraits. Using this, return key will be disabled when no input text is available within text field.

- 2,917
- 23
- 46
- 68

- 3,241
- 7
- 31
- 33
-
2In Swift: textfield.enablesReturnKeyAutomatically = true – AmyNguyen Oct 05 '16 at 03:07
-
3Might sound silly, but I wanted this answer when I came here. Like I think a lot of people do, I blindly clicked on the first link that came up in google, skipped the question entirely and read the first couple of answers – Joe Pinsonault Apr 30 '17 at 02:26
You can override UITextField
's hasText
attribute to achieve this:
class CustomTextField : UITextField {
override public var hasText: Bool {
get {
return evaluateString(text)
}
}
}
Where evaluateString(_ text: String?) -> Bool
checks against your needed input criteria, for example character count.
Of course this does only work in combination with enablesReturnKeyAutomatically = true
set on the UITextField
.
I am aware that my answer is neither timely nor written in Objective-C, but given that I have not been able to find an answer anywhere else and this question being routinely referred to in other threads, I think that here is the best place to post it.

- 321
- 3
- 4
UITextField
's enablesReturnKeyAutomatically
property can be set right in Interface Builder, just select the textfield and open the Attributes inspector. As Tharindu stated, this will automatically enable and disable the return key depending on whether any text has been entered.
Of course, if you need to change this in code you can still set it programmatically using nameTextField.enablesReturnKeyAutomatically = true
.
EDIT to address the downvotes:
Otherwise, there is no official way to enable and disable the return key on command. I would recommend against trying to use private APIs to accomplish this. Alternatively, you can use the textFieldShouldReturn:
delegate method and put your conditional/validation there and respond accordingly.

- 38,547
- 26
- 130
- 141
One good idea is to create one file to access this class from anywhere. Here is the code:
UIKeyboard.h
#import <UIKit/UIKit.h>
@interface UIApplication (KeyboardView)
- (UIView *)keyboardView;
@end
UIKeyboard.m
#import "UIKeyboard.h"
@implementation UIApplication (KeyboardView)
- (UIView *)keyboardView
{
NSArray *windows = [self windows];
for (UIWindow *window in [windows reverseObjectEnumerator])
{
for (UIView *view in [window subviews])
{
if (!strcmp(object_getClassName(view), "UIKeyboard"))
{
return view;
}
}
}
return nil;
}
@end
Now you can import and access this class from your own class:
#import "UIKeyboard.h"
// Keyboard Instance Pointer.
UIView *keyboardView = [[UIApplication sharedApplication] keyboardView];
A full documentation of this class you can find here: http://ericasadun.com/iPhoneDocs/_u_i_keyboard_8h-source.html
More information you can find here: http://cocoawithlove.com/2009/04/showing-message-over-iphone-keyboard.html

- 26,840
- 19
- 119
- 186

- 1,605
- 12
- 9
-
13
-
I don't think this is worthy of a rejection. We're only iterating over subviews and picking the one we like. Its handy however, doesn't answer the question which is about disabling the return key. – Rushabh Apr 09 '18 at 17:41
-
1This is just a really bad idea... other than Apple rejecting you, the system setup could change without you knowing and break this solution. – Zorayr May 29 '20 at 22:17
Let me suggest a bit hacky solution which requires no subclassing.
extension UITextFieldDelegate {
func setReturnKeyState(for textField: UITextField, isEnabled: Bool, delay: Double? = nil) {
textField.enablesReturnKeyAutomatically = false
if textField.delegate != nil {
if let delay = delay {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
textField.setValue(isEnabled, forKeyPath: "inputDelegate.returnKeyEnabled")
}
} else {
textField.setValue(isEnabled, forKeyPath: "inputDelegate.returnKeyEnabled")
}
}
}
}
Usage practical sample
Define any condition, for example like this:
private func validateInput(_ string: String?) -> Bool {
(string?.count ?? 0) > 3
}
Call setReturnKeyState
in delegate methods, for example:
func textFieldDidBeginEditing(_ textField: UITextField) {
setReturnKeyState(for: textField, isEnabled: validateInput(textField.text), delay: 0.1) // A bit hacky it needs delay here
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if var text = textField.text, let range = Range(range, in: text) {
text.replaceSubrange(range, with: string)
setReturnKeyState(for: textField, isEnabled: validateInput(text))
}
return true
}

- 3,989
- 33
- 46
-
1My only concern on your excellent solution is the fragility of it over time. – David H Mar 13 '22 at 15:25
-
1I have the same concern myself, @David. I can only recommend to make a test for the function in question to eliminate unexpectedness in production. – Paul B Mar 13 '22 at 16:37
-
In the end, after all these years, Apple just s*cks for not just giving us this small thing after all these years. Oh how I miss Steve who actually responded to our emails. – David H Mar 14 '22 at 02:09
My answer to the duplicate question, copied over:
All the other solutions do not answer the question. OP wants to "gray" out the return button on the keyboard as a visual signal to the user.
Here is my solution, working on iOS 13. You may have to modify the solution slightly for other iOS versions.
First, I extend UITextFieldDelegate
.
func getKeyboard() -> UIView?
{
for window in UIApplication.shared.windows.reversed()
{
if window.debugDescription.contains("UIRemoteKeyboardWindow") {
if let inputView = window.subviews
.first? // UIInputSetContainerView
.subviews
.first // UIInputSetHostView
{
for view in inputView.subviews {
if view.debugDescription.contains("_UIKBCompatInputView"), let keyboard = view.subviews.first, keyboard.debugDescription.contains( "UIKeyboardAutomatic") {
return keyboard
}
}
}
}
}
return nil
}
Then, whenever I need to disable the "return" key, we can do (replace delegate
with the variable name of your delegate object):
if let keyboard = delegate.getKeyboard(){
keyboard.setValue(text == nil, forKey: "returnKeyEnabled")
}

- 340
- 2
- 9
-
That's a brittle solution that could break in any minor release without notice and Apple prohibits using non-public undocumented interfaces like "_UIKBCompatibleInputView" in apps on the app store. While this is a very cool feat of reverse engineering and interesting to see intellectually, I wouldn't recommend doing this in a production app unless the need was extremely high and no better supported/maintainable workarounds are available. I also would steer clear unless I was willing to come back and re-hack the code in a hurry if Apple ever changed something. App revenue disruption risk? – clearlight Aug 08 '22 at 21:17
-
I'm just answering the OP's question to the best of my ability. Moreover, this setting is not prohibited. We are using a public method of `setValue` here. Could it break? Yes. – Winston Du Aug 12 '22 at 00:39
-
No worries - it's informative/educational to show these hacks, but should be made super clear the downsides of using them in real-world applications. These tend to look like free candy and great fun for inexperienced developers who can (and do) easily waste a lot of time and get a lot of grief down the road by naively creating too much dependence on hacks like these. If someone's selling an app on a store, maybe they are too busy or don't have access to fix it on short-notice if a minor release breaks it, and it puts them in a bad situation in terms of time and money. – clearlight Aug 12 '22 at 16:14
Here is a technique that is available from the documented API, but it does not provide visual feedback when the enter key is disabled.
- (void)setup {
// Or in init
self.textField.delegate = self;
}
// <UITextFieldDelegate>
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// substitute your test here
return [textField.text rangeOfString:@"@"].location != NSNotFound;
}
Other answers here can be used with
[textField addTarget:self
action:@selector(validateTextField:)
forControlEvents:UIControlEventEditingChanged];
to provide dynamic visual feedback as the user types.

- 774
- 6
- 12