Skip to content

Instantly share code, notes, and snippets.

@DaisukeNagata
Created December 17, 2019 11:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DaisukeNagata/50a90621dd68e5353786a643315088b6 to your computer and use it in GitHub Desktop.
Save DaisukeNagata/50a90621dd68e5353786a643315088b6 to your computer and use it in GitHub Desktop.
SwiftUI_UITexTField_CaretLogic
import UIKit
import SwiftUI
struct ContentView: View {
@State var text: String = ""
@State var text2: String = ""
@State var spacing: CGFloat = 0
@State var didTap = false
var body: some View {
VStack {
HStack(alignment: .bottom, spacing: spacing) {
SATextField(tag: 0, placeholder: "placeholder", changeHandler: { (newString) in
self.text = newString
}, onCommitHandler: {
// write something
})
self.text.isEmpty == false ?
HorizontalLine(color: self.didTap ? Color.red : Color.black) :
HorizontalLine(color: self.didTap ? Color.black : Color.red)
SATextField(tag: 1, placeholder: "placeholder2", changeHandler: { (newString) in
self.text2 = newString
}, onCommitHandler: {
// write something
})
text2.isEmpty == false ?
HorizontalLine(color: didTap ? Color.red : Color.black) :
HorizontalLine(color: didTap ? Color.black : Color.red)
}
}.position(.init(x: UIScreen.main.bounds.width/2+50, y: UIScreen.main.bounds.height/2))
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct HorizontalLine: View {
private var color: Color? = nil
private var height: CGFloat = 1.0
private var shape: HorizontalLineShape?
init(color: Color, height: CGFloat = 1.0) {
self.color = color
self.height = height
}
var body: some View {
HorizontalLineShape().fill(self.color!).frame(minWidth: 0, maxWidth: .infinity, minHeight: height, maxHeight: height)
}
}
struct HorizontalLineShape: Shape {
func path(in rect: CGRect) -> Path {
let fill = CGRect(x: -rect.size.width, y: 0, width: rect.size.width, height: rect.size.height)
var path = Path()
path.addRoundedRect(in: fill, cornerSize: CGSize(width: 2, height: 2))
return path
}
}
class Model: ObservableObject {
@Published var text = ""
var placeholder = "Placeholder"
}
// check is this
// https://medium.com/@valv0/textfield-and-uiviewrepresentable-46a8d3ec48e2
struct SATextField: UIViewRepresentable {
private let tmpView = WrappableTextField()
//var exposed to SwiftUI object init
var tag:Int = 0
var placeholder:String?
var changeHandler:((String)->Void)?
var onCommitHandler:(()->Void)?
func makeUIView(context: UIViewRepresentableContext<SATextField>) -> WrappableTextField {
tmpView.tag = tag
tmpView.delegate = tmpView
tmpView.placeholder = placeholder
tmpView.onCommitHandler = onCommitHandler
tmpView.textFieldChangedHandler = changeHandler
return tmpView
}
func updateUIView(_ uiView: WrappableTextField, context: UIViewRepresentableContext<SATextField>) {
uiView.setContentHuggingPriority(.defaultHigh, for: .vertical)
uiView.setContentHuggingPriority(.defaultLow, for: .horizontal)
}
}
class WrappableTextField: UITextField, UITextFieldDelegate {
var textFieldChangedHandler: ((String)->Void)?
var onCommitHandler: (()->Void)?
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let nextField = textField.superview?.superview?.viewWithTag(textField.tag + 1) as? UITextField {
nextField.becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
return false
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let currentValue = textField.text as NSString? {
let proposedValue = currentValue.replacingCharacters(in: range, with: string)
textFieldChangedHandler?(proposedValue as String)
}
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
onCommitHandler?()
}
}
@DaisukeNagata
Copy link
Author

giImage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment