How can I preselect Caps lock for a specific textField? - swift

When I begin to type, I want CapsLock to be preselected on the keyboard so I just type everything in Caps lock.

From Apple docs
The UITextInputTraits protocol defines features associated with keyboard input to a text object. For a custom text object to support keyboard input, it must adopt this protocol to interact properly with the text input management system. The UITextField and UITextView classes automatically support this protocol.
The auto-capitalization behavior of a text-based view. Used with the autocapitalizationType property.
enum UITextAutocapitalizationType : Int {
case None
case Words
case Sentences
case AllCharacters
}
You can achieve auto capitalisation of all characters by:
textField.autocapitalizationType = .allCharacters

If you want letters always capital on the textField, even if the user switches the Caps Lock button on the keyboard, you can use UITextFieldDelegate's textFieldDidChange method and set the text to be always uppercased, like this:
func textFieldDidChange(_ textField: UITextField) {
textField.text = textField.text?.uppercased()
}

Related

Passing keyboard events from NSTextView to another

I have NSTextView which pops up a NSPopOver that contains another NSTextView. In some cases, I'd like to pass the keyboard events (arrow keys, mostly) from the "top" text view to the bottom one.
I have overridden keyDown on the topmost text view and tried various ways of forwarding the keyboard event to the view below.
Just calling bottomTextView.keyDown(with: event) doesn't do anything. The closest I've gotten is using window.sendEvent(event).
override func keyDown(with event: NSEvent) {
if (NSLocationInRange(Int(event.keyCode), NSMakeRange(123, 4)) &&
self.string.count == 0 && event.modifierFlags.contains(.shift)) {
// Pass the event through somehow
return
}
super.keyDown(with: event)
}
Through trial and error, I found one way which actually did pass on the events: calling the methods twice.
// Make the bottom text field first responder
self.window?.makeFirstResponder(self.delegate.bottomTextView)
self.window?.makeFirstResponder(self.delegate.bottomTextView)
// Send the keydown event to window
self.window?.sendEvent(event)
self.window?.sendEvent(event)
However, this causes strange issues, such as the topmost text view getting a one-byte string as its contents.
Is there a correct way to actually forward any key events from a text view to another, or is it even possible?

NSSearchField - How to select all text? (Swift/Storyboards on macOS)

It seems everything online is mostly about iOS/UI controls, not macOS/Cocoa NS controls. Anyway, How does one make an NSSearchField select all text in the field programatically? I have tried multiple methods adapted from the iOS UISearchBar implementations, but none of them compiled or worked. I just want to, for instance, press a button and have it hilight the text that is inside the NSSearchField's text field. I can't seem to find a method within it that allows this to happen.
Thank you for your help/consideration!
All editing in NSTextField is handled by NSText (which inherits from NSTextView). So, to select the text in your search field, you need to set the selected range in field's current editor. This example highlights the whole text.
Objective-C:
NSRange range = NSMakeRange(0, searchField.stringValue.length);
NSText *editor = [searchField currentEditor];
[editor setSelectedRange:range];
Swift
let range = NSRange(location: 0, length: searchField.stringValue.length)
let editor = searchField.currentEditor()
editor?.selectedRange = range

Delete command is not working for NSTextField

I have a textfield to which I need to listen to tab key, so that when ever the user press tab from that text field I can move the focus to next text field. I have implemented the below code to perform that operation.
func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
if (commandSelector == #selector(insertTab)) {
if control == firstTextField {
makeNextTextFieldAsFirstResponder()
}
}
return true
}
My problem is that as I have implemented this code, delete key is not doing what it suppose to do(removing last character from the text field's text). Am I missing something here?
I am new to Mac development so excuse me if this question has been asked already somewhere.
I found the solution to my own problem. It turns out to be a simple mistake. I am not sure about how exactly this method works and how the return value affect the nature of the text field as I am new to Mac development, but it seems that the default return value should be false. Any insights to this behaviour are welcome.

Changing the text of a UITextField does not trigger the rx.text binder

I have a UITextField called commentField and I create an Observable<Bool> like this:
let isCommentFieldValid = self.commentField.rx.text.orEmpty.map({ !$0.isEmpty })
This observable determines whether a button is enabled or not.
The problem is that when I change the text property of commentField liked this:
self.commentField.text = ""
The isCommentFieldValid doesn't trigger again and, thus, the button's state doesn't change. Any edition using the UI works: if I remove all text from the field through the keyboard, the isCommentFieldValid updates, but via code it doesn't.
Is there a reason this doesn't work?
If you look at the underlying implementation for rx.text you'll see that it relies on the following UIControlEvents: .allEditingEvents and .valueChanged. Explicitly setting the text property on UITextField does not send actions for these events, so your observable is not updated. You could try sending an action explicitly:
self.commentField.text = ""
self.commentField.sendActions(for: .valueChanged)

Change UITextField behavior

What is the best way to disable UITextField's 'return' keyboard key if input area does not contain any text? UITextField with enablesReturnKeyAutomatically property set to YES enables return key even if there are only spaces entered, but I'd like it to enable return key only when the text is not empty. any suggestions?
I don't know how you'd override the text input trait behaviour, but you could use the text field delegate method textField:shouldChangeCharactersInRange:replacementString: to prevent the user being able to enter spaces into an otherwise blank string. This would prevent any whitespace text being added, so the return key should not be enabled.
If you're not bothered about the return key actually being enabled, you could use textFieldShouldReturn:, again one of the text field delegate methods.
I would do something like the following
Create an extension to String and add a trim method (it will become handy in other scenarios too that's why I suggest an extension.
public func trim() -> String {
return stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
}
Make your class a delegate of UITextFieldDelegate and add the following fuction
func textFieldDidChange(textField: UITextField) {
textField.text = textField.text.trim()
}
Set the delegate of your UITextField to self.