How do i select all text when clicking inside the textfield? Just like how a web browser like chrome would when you click inside the address bar.
import SwiftUI
import AppKit
struct ContentView: View {
var body: some View {
TextField("Enter a URL", text: $site)
}
}
SwiftUI Solution:
struct ContentView: View {
var body: some View {
TextField("Placeholder", text: .constant("This is text data"))
.onReceive(NotificationCenter.default.publisher(for: UITextField.textDidBeginEditingNotification)) { obj in
if let textField = obj.object as? UITextField {
textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
}
}
}
}
Note : import Combine
Use UIViewRepresentable and wrap UITextField and use textField.selectedTextRange property with delegate.
Here is the sample demo
struct HighlightTextField: UIViewRepresentable {
#Binding var text: String
func makeUIView(context: Context) -> UITextField {
let textField = UITextField()
textField.delegate = context.coordinator
return textField
}
func updateUIView(_ textField: UITextField, context: Context) {
textField.text = text
}
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
class Coordinator: NSObject, UITextFieldDelegate {
var parent: HighlightTextField
init(parent: HighlightTextField) {
self.parent = parent
}
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
}
}
}
For macOS
struct HighlightTextField: NSViewRepresentable {
#Binding var text: String
func makeNSView(context: Context) -> CustomTextField {
CustomTextField()
}
func updateNSView(_ textField: CustomTextField, context: Context) {
textField.stringValue = text
}
}
class CustomTextField: NSTextField {
override func mouseDown(with event: NSEvent) {
if let textEditor = currentEditor() {
textEditor.selectAll(self)
}
}
}
Here is my solution
import SwiftUI
import PlaygroundSupport
struct ContentView: View {
#State private var renameTmpText: String = ""
#FocusState var isFocused: Bool
#State private var textSelected = false
var body: some View {
TextEditor(text: $renameTmpText)
.padding(3)
.border(Color.accentColor, width: 1)
.frame(width: 120, height: 40)
.onExitCommand(perform: {
renameTmpText = ""
})
.onAppear {
renameTmpText = "Test"
isFocused = true
}
.focused($isFocused)
.onReceive(NotificationCenter.default.publisher(for: NSTextView.didChangeSelectionNotification)) { obj in
if let textView = obj.object as? NSTextView {
guard !textSelected else { return }
let range = NSRange(location: 0, length: textView.string.count)
textView.setSelectedRange(range)
textSelected = true
}
}
.onDisappear { textSelected = false }
}
}
let view = ContentView()
PlaygroundPage.current.setLiveView(view)
I've created a ViewModifier to select all the text in a TextField.
Only downside is, it won't work with multiple TextFields.
public struct SelectTextOnEditingModifier: ViewModifier {
public func body(content: Content) -> some View {
content
.onReceive(NotificationCenter.default.publisher(for: UITextField.textDidBeginEditingNotification)) { obj in
if let textField = obj.object as? UITextField {
textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
}
}
}
}
extension View {
/// Select all the text in a TextField when starting to edit.
/// This will not work with multiple TextField's in a single view due to not able to match the selected TextField with underlying UITextField
public func selectAllTextOnEditing() -> some View {
modifier(SelectTextOnEditingModifier())
}
}
usage:
TextField("Placeholder", text: .constant("This is text data"))
.selectAllTextOnEditing()
I have several TextFields in my View and I would like change the language of the keyboard depending on in which TextField the user tapped. I know I can change the type like .numberPad, but how for languages?
If the user has added the language to his keyboards you can make a custom textfield and do the following:
create a custom textfield and textfield view
import Foundation
import UIKit
import SwiftUI
class SpecificLanguageTextField: UITextField {
var language: String? {
didSet {
if self.isFirstResponder{
self.resignFirstResponder();
self.becomeFirstResponder();
}
}
}
override var textInputMode: UITextInputMode? {
if let language = self.language {
for inputMode in UITextInputMode.activeInputModes {
if let inputModeLanguage = inputMode.primaryLanguage, inputModeLanguage == language {
return inputMode
}
}
}
return super.textInputMode
}
}
struct SpecificLanguageTextFieldView: UIViewRepresentable {
let placeHolder: String
var language: String = "en-US"
#Binding var text: String
func makeUIView(context: Context) -> UITextField{
let textField = SpecificLanguageTextField(frame: .zero)
textField.placeholder = self.placeHolder
textField.text = self.text
textField.language = self.language
return textField
}
func updateUIView(_ uiView: UITextField, context: Context) {
}
}
And then use it like this:
import SwiftUI
struct SpecificLanguageView: View {
#State var text: String = ""
var body: some View {
SpecificLanguageTextFieldView(placeHolder: "test", language: "en-GB", text: $text)
}
}
struct SpecificLanguageView_Previews: PreviewProvider {
static var previews: some View {
SpecificLanguageView()
}
}
_ = textField.rx.text.orEmpty.filter({ (text) -> Bool in
text.count > 12
return true
}).subscribe(onNext: { (text) in
let tempText:String = text
self.textField.text = (tempText as NSString).substring(to: 12)
})
it has someBug,i need use textFieldDidEndEditing
You can use delegate proxy pattern in RxSwift.
First we need to set delegate UITextField to DelegateProxyType
class RxTextFieldDelegateProxy: DelegateProxy<UITextField, UITextFieldDelegate>, DelegateProxyType, UITextFieldDelegate {
init(textField: UITextField) {
super.init(parentObject: textField, delegateProxy: RxTextFieldDelegateProxy.self)
}
static func registerKnownImplementations() {
self.register { RxTextFieldDelegateProxy(textField: $0)}
}
static func currentDelegate(for object: UITextField) -> UITextFieldDelegate? {
return object.delegate
}
static func setCurrentDelegate(_ delegate: UITextFieldDelegate?, to object: UITextField) {
object.delegate = delegate
}
}
Second we can define properties by ourself in RxSwift.
extension Reactive where Base: UITextField {
public var delegate: DelegateProxy<UITextField, UITextFieldDelegate> {
return RxTextFieldDelegateProxy.proxy(for: base)
}
public var editingDidEnd: Observable<String> {
return delegate.sentMessage(#selector(UITextFieldDelegate.textFieldDidEndEditing(_:))).map { value in
guard let textField = value[0] as? UITextField else { return "" }
return textField.text! }
}
}
Third usage:
myTextField.rx.editingDidEnd.subscribe(onNext: { value in
debugPrint(value)
}).disposed(by: bag)
RxSwift 4.0
If you want to user UITextField delegate method you have use `controlEvent.
var bag = DisposeBag()
Now put observer in viewDidLoad method.
override func viewDidLoad() {
super.viewDidLoad()
controls.txtTitle.rx
.controlEvent([.editingDidEnd])
.asObservable()
.subscribe(onNext: {
print("Editing done")
}).disposed(by: bag)
}
I work on a custom keyboard (My Keyboard is no xib or StoryBoard),
I want to know if I can choose the background to remain constant
according to the choice The custom keyboard on
For example: When I choose the keyboard to keyboard Dark then stay in the selected mode "Dark".
And when I want to change the background again to be in the Light then again to stay in the selected mode "Light".
This would look like:
KeyboardInputTraits.swift
func pollTraits() {
if let proxy = (self.textDocumentProxy as? UITextInputTraits) {
if let layout = self.layout {
let appearanceIsDark = (proxy.keyboardAppearance == UIKeyboardAppearance.Dark)
if appearanceIsDark != layout.darkMode {
self.updateAppearances(appearanceIsDark)
}
}
}
}
KeyboardViewController.swift
func darkMode() -> Bool {
var darkMode = { () -> Bool in
if let proxy = self.textDocumentProxy as? UITextDocumentProxy {
return proxy.keyboardAppearance == UIKeyboardAppearance.Dark
}
else {
return false
}
}()
return darkMode
}
I am working on the code below to check the textField1 and textField2 text fields whether there is any input in them or not.
The IF statement is not doing anything when I press the button.
#IBOutlet var textField1 : UITextField = UITextField()
#IBOutlet var textField2 : UITextField = UITextField()
#IBAction func Button(sender : AnyObject)
{
if textField1 == "" || textField2 == ""
{
//then do something
}
}
Simply comparing the textfield object to the empty string "" is not the right way to go about this. You have to compare the textfield's text property, as it is a compatible type and holds the information you are looking for.
#IBAction func Button(sender: AnyObject) {
if textField1.text == "" || textField2.text == "" {
// either textfield 1 or 2's text is empty
}
}
Swift 2.0:
Guard:
guard let text = descriptionLabel.text where !text.isEmpty else {
return
}
text.characters.count //do something if it's not empty
if:
if let text = descriptionLabel.text where !text.isEmpty
{
//do something if it's not empty
text.characters.count
}
Swift 3.0:
Guard:
guard let text = descriptionLabel.text, !text.isEmpty else {
return
}
text.characters.count //do something if it's not empty
if:
if let text = descriptionLabel.text, !text.isEmpty
{
//do something if it's not empty
text.characters.count
}
Better and more beautiful use
#IBAction func Button(sender: AnyObject) {
if textField1.text.isEmpty || textField2.text.isEmpty {
}
}
another way to check in realtime textField source :
#IBOutlet var textField1 : UITextField = UITextField()
override func viewDidLoad()
{
....
self.textField1.addTarget(self, action: Selector("yourNameFunction:"), forControlEvents: UIControlEvents.EditingChanged)
}
func yourNameFunction(sender: UITextField) {
if sender.text.isEmpty {
// textfield is empty
} else {
// text field is not empty
}
}
if let ... where ... {
Swift 3:
if let _text = theTextField.text, _text.isEmpty {
// _text is not empty here
}
Swift 2:
if let theText = theTextField.text where !theTextField.text!.isEmpty {
// theText is not empty here
}
guard ... where ... else {
You can also use the keyword guard :
Swift 3:
guard let theText = theTextField.text where theText.isEmpty else {
// theText is empty
return // or throw
}
// you can use theText outside the guard scope !
print("user wrote \(theText)")
Swift 2:
guard let theText = theTextField.text where !theTextField.text!.isEmpty else {
// the text is empty
return
}
// you can use theText outside the guard scope !
print("user wrote \(theText)")
This is particularly great for validation chains, in forms for instance. You can write a guard let for each validation and return or throw an exception if there's a critical error.
As now in swift 3 / xcode 8 text property is optional you can do it like this:
if ((textField.text ?? "").isEmpty) {
// is empty
}
or:
if (textField.text?.isEmpty ?? true) {
// is empty
}
Alternatively you could make an extenstion such as below and use it instead:
extension UITextField {
var isEmpty: Bool {
return text?.isEmpty ?? true
}
}
...
if (textField.isEmpty) {
// is empty
}
use this extension
extension String {
func isBlankOrEmpty() -> Bool {
// Check empty string
if self.isEmpty {
return true
}
// Trim and check empty string
return (self.trimmingCharacters(in: .whitespaces) == "")
}
}
like so
// Disable the Save button if the text field is empty.
let text = nameTextField.text ?? ""
saveButton.isEnabled = !text.isBlankOrEmpty()
A compact little gem for Swift 2 / Xcode 7
#IBAction func SubmitAgeButton(sender: AnyObject) {
let newAge = String(inputField.text!)
if ((textField.text?.isEmpty) != false) {
label.text = "Enter a number!"
}
else {
label.text = "Oh, you're \(newAge)"
return
}
}
Maybe i'm a little too late, but can't we check like this:
#IBAction func Button(sender: AnyObject) {
if textField1.text.utf16Count == 0 || textField2.text.utf16Count == 0 {
}
}
Okay, this might be late, but in Xcode 8 I have a solution:
if(textbox.stringValue.isEmpty) {
// some code
} else {
//some code
}
I used UIKeyInput's built in feature hasText: docs
For Swift 2.3 I had to use it as a method instead of a property (as it is referenced in the docs):
if textField1.hasText() && textField2.hasText() {
// both textfields have some text
}
Swift 4.x Solution
#IBOutlet var yourTextField: UITextField!
override func viewDidLoad() {
....
yourTextField.addTarget(self, action: #selector(actionTextFieldIsEditingChanged), for: UIControlEvents.editingChanged)
}
#objc func actionTextFieldIsEditingChanged(sender: UITextField) {
if sender.text.isEmpty {
// textfield is empty
} else {
// text field is not empty
}
}
Swift 4.2
You can use a general function for your every textField just add the following function in your base controller
// White space validation.
func checkTextFieldIsNotEmpty(text:String) -> Bool
{
if (text.trimmingCharacters(in: .whitespaces).isEmpty)
{
return false
}else{
return true
}
}
I just tried to show you the solution in a simple code
#IBAction func Button(sender : AnyObject) {
if textField1.text != "" {
// either textfield 1 is not empty then do this task
}else{
//show error here that textfield1 is empty
}
}
It's too late and its working fine in Xcode 7.3.1
if _txtfield1.text!.isEmpty || _txtfield2.text!.isEmpty {
//is empty
}
Swift 4/xcode 9
IBAction func button(_ sender: UIButton) {
if (textField1.text?.isEmpty)! || (textfield2.text?.isEmpty)!{
..............
}
}
Easy way to Check
if TextField.stringValue.isEmpty {
}