I want to set the cursor to the end of the TextField like this image1
This is want I have image2
Can anyone give advice?
only this time :)
Form {
HStack {
Text("User Name")
TextField("user",text: $user)
.multilineTextAlignment(.trailing)
}
HStack {
Text("Password")
TextField("password",text: $password)
.multilineTextAlignment(.trailing)
}
}
Related
i want to put some fixed text inside TextField like "email: ....."
I tryed this:
HStack {
Image(systemName: "list.bullet").foregroundColor(.gray)
Text("email:")
TextField("", text: Binding(
get: { viewModel.email },
set: { viewModel.email = $0 }
))
.textFieldStyle(DefaultTextFieldStyle())
.frame(width: 60)
}
.padding()
.overlay(RoundedRectangle(cornerRadius: 10).stroke(
viewModel.emailValid() ? Color.gray : Color.red, lineWidth: 1
))
The problem is that this implementation only allows to click in specific part (inside the textField space) but i want to make all clickable to be more friendly to edit.
I tryed putting TextField and Text inside ZStack but the text entered by the user in inside te "Email text".
Maybe its possible to move the textField cursor to the end of the "email" text, or another implementation?
Thanks!
So if its mainly about activating the TextField on tap/click on any area of the element, you can use programmatic focus for TextField:
struct ContentView: View {
#State var input = ""
#FocusState var focused: Bool
var body: some View {
HStack {
Image(systemName: "list.bullet").foregroundColor(.gray)
Text("email:")
TextField("", text: $input)
.frame(width: 80)
.focused($focused)
}
.padding()
.overlay(RoundedRectangle(cornerRadius: 10).stroke(
true ? Color.gray : Color.red, lineWidth: 1
))
.contentShape(Rectangle()) // makes the whole element tappable
.onTapGesture {
focused = true // sets focus for textField
}
}
}
NavigationView{
List{
VStack{
Text("EdwardCullen")
.padding(.vertical, -20)
AsyncImage(url)) { image in
image
.center()
} placeholder: {
ProgressView()
}
}
Text("Test")
}
.navigationTitle("EdwardCullen's Profile")
.navigationBarTitleDisplayMode(.inline)
}
Picture of what I want
I included a picture of what I want kind of, so basically "Status" on the left side of the Text and "Online" on the total other side. I also would preferably want "Online" to be green, so I think I need to use two different Text views, but how exactly would I do this in a list? Is there any good way to do this?
The way I did what is in the picture is just adding many spaces to Text like this, but obviously that is not very smart and also not exactly what I want.
Text("First Second")
Use HStack{} plus Spacer(). (Code is below the image)
var body: some View {
VStack {
HStack {
Text("First")
Spacer() //this one
Text("Second")
}
.padding()
.background(.blue)
.cornerRadius(15)
}
}
Use a spacer "Spacer()". This is an adaptive view that expands as much as it can.
NavigationView{
List{
VStack{
Text("EdwardCullen")
.padding(.vertical, -20)
AsyncImage(url)) { image in
image
.center()
} placeholder: {
ProgressView()
}
}
# new code here
HStack {
Text("Status")
Spacer()
Text("Online")
.foregroundColor(.green)
}
}
.navigationTitle("EdwardCullen's Profile")
.navigationBarTitleDisplayMode(.inline)
}
Just Use a HStack and put a spacer between two text .
sample code :
HStack{
Text("Status")
Spacer()
Text("Online")
}.cornerRadius(8)
you may use this anywhere you want .
Sample Output:
I am writing a SwiftUI iOS app where I need a Text view to automatically scroll to the end of its content whenever the content is updated. The update happens from the model. To not complicate this question with the details of my app, I have created a simple scenario where I have two text fields and a text label. Any text entered in the text fields is concatenated and shown in the text label. The text label is enclosed in a horizontal ScrollView and can be scrolled manually if the text is longer than the screen width. What I want to achieve is for the text to scroll to the end automatically whenever the label is updated.
Here is the simple model code:
class Model: ObservableObject {
var firstString = "" {
didSet { combinedString = "\(firstString). \(secondString)." }
}
var secondString = "" {
didSet { combinedString = "\(firstString). \(secondString)." }
}
#Published var combinedString = ""
}
This is the ContentView:
struct ContentView: View {
#ObservedObject var model: Model
var body: some View {
VStack(alignment: .leading, spacing: 10) {
TextField("First string: ", text: $model.firstString)
TextField("Second string: ", text: $model.secondString)
Spacer().frame(height: 20)
Text("Combined string:")
ScrollView(.horizontal) {
Text(model.combinedString)
}
}
}
}
From the research I have done, the only way I have found to scroll to the end of the text, without having to do it manually, is to add a button to the view, which causes the text in the label to scroll to the end.
Here is the above ScrollView embedded in a ScrollViewReader, with a button to effect the scrolling action.
ScrollViewReader { scrollView in
VStack {
ScrollView(.horizontal) {
Text(model.combinedString)
.id("combinedText")
}
Button("Scroll to end") {
withAnimation {
scrollView.scrollTo("combinedText", anchor: .trailing)
}
}
.padding()
.foregroundColor(.white)
.background(Color.black)
}
}
This works, provided the intention is to use a button to effect the scrolling action.
My question is: Can the scrolling action above be triggered whenever the model is updated, without the need to click a button.
Any help or pointers will be much appreciated.
Thanks.
I assume you wanted this:
ScrollViewReader { scrollView in
VStack {
ScrollView(.horizontal) {
Text(model.combinedString)
.id("combinedText")
}
.onChange(of: model.combinedString) { // << here !!
withAnimation {
scrollView.scrollTo("combinedText", anchor: .trailing)
}
}
}
}
ScrollViewReader is the solution you're looking for. You may need to play around with the value. Also you'll need to add the .id(0) modifier to your textview.
ScrollView {
ScrollViewReader { reader in
Button("Go to first then anchor trailing.") {
value.scrollTo(0, anchor: .trailing)
}
// The rest of your code .......
Given a basic List with Text, how can i make the whole "cell" from left side of the screen to right, tappable in a List, not just the "Hello world" text?
List {
VStack {
Text("Hello world")
}
.contentShape(Rectangle())
.onTapGesture {
print("Tapped cell") // This only triggers when you directly tap the Text
}
}
Add a Button and entire cell is tappable now:
VStack {
Button(action: {
print("Tapped")
}) {
Text("Hello world")
}
}
Actually, all you really need to do is make sure the entire cell is filled with content. Changing the VStack to an HStack and adding a Spacer() will give you what you want.
List {
HStack {
Text("Hello world")
Spacer()
}
.contentShape(Rectangle())
.onTapGesture {
print("Tapped cell") // This triggers when you tap anywhere in the cell
}
}
The textField on my SwiftUI app is getting cut off. But it doesn't happen every time. It seems to happen at random.
Here is the code I'm using:
var body: some View {
VStack {
Spacer()
// Target row
HStack {
Text("Put the bullseye as close as you can to:")
Text("\(target)")
}
Spacer()
// Slider row
HStack {
Text("1")
Slider(value: $sliderValue, in: 1...100) {_ in
print(self.sliderValue)
}
Text("100")
}
Spacer()
// Hit me button row
Button(action: {
print("Button pressed")
self.alertIsVisible = true
}) {
Text(/*#START_MENU_TOKEN#*/"Hit Me!"/*#END_MENU_TOKEN#*/)
}
.alert(isPresented: $alertIsVisible) { () -> Alert in
let roundedValue = Int(sliderValue.rounded())
let score = pointsForCurrentRound()
return Alert(title: Text("Hello there!"), message: Text("The slider's value is \(roundedValue)!\n" +
"You scored \(score) points this round"
), dismissButton: .default(Text("Awesome")))
}
Spacer()
// Score and start over button row
HStack {
Button(action: /*#START_MENU_TOKEN#*/{}/*#END_MENU_TOKEN#*/) {
Text("Start Over")
}
Spacer()
Text("Score:")
Text("999999")
Spacer()
Text("Round:")
Text("999")
Spacer()
Button(action: /*#START_MENU_TOKEN#*/{}/*#END_MENU_TOKEN#*/) {
Text("Info")
}
}
.padding(.bottom, 20)
}
}
I've tried adding padding trailing the text field and before the target. I've tried adding padding to the leading edge of the target. I've tried giving using the frame method on the text field to add a min length. None of these work. Any ideas?
Thanks
You may add fixedSize() to lock the labels.
HStack {
Text("Put the bullseye as close as you can to:").fixedSize()
Text("\(target)").fixedSize()
}
I just came across this exact situation! After a few moments of searching, trial, and errors, I finally figured it out. The text view is trying to resize and one of the parent views have animations enabled. If anyone having this same issue adds .animation(nil) to the Text, this will likely solve the issue.
VStack {
Text("\(Int(self.viewModel.ProgressPercentage * 100.0))%")
.font(.largeTitle)
.animation(nil)
}
Good luck!