I am trying to learn swiftui and faced with "markup" problem. I need to build a UI with textfield in a toolbar (like address line in Safari):
I've tried to do it like this:
import SwiftUI
struct ContentView: View {
#State var searchText: String = ""
var body: some View {
NotesListView(notesRepo: InMemoryNotesStubRepository())
.frame(minWidth: 500, minHeight: 300)
.toolbar {
ToolbarItem(placement: .primaryAction){
TextField("Search", text: $searchText)
.frame(minWidth: 300)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
And I've got something weird:
Can anyone help me how to add a textfield to a toolbar like in is in Safari (address line)?
It is possible to use style for TextField, like
ToolbarItem(placement: .primaryAction){
TextField("Search", text: $searchText)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(minWidth: 300)
}
of even custom style with with look & feel you need, see next for example https://stackoverflow.com/a/63976054/12299030
Related
Prior to iOS 16, screen background in a NavigationView used to work very reliably in SwiftUI.
In iOS 16, there is a hollow space (without background color) when navigating back and forth with on-screen-keyboard:
Repro code:
import SwiftUI
struct ContentView: View {
#State private var text: String = ""
var body: some View {
NavigationView {
VStack {
TextField("Edit field", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
NavigationLink(destination: Text("Naviagtion target")) {
HStack {
Image(systemName: "link")
Text("Navigation Link")
}
}
.padding(30)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.gray)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Any ideas how to fix this?
It does look and feel like a bug, where the safe area that’s adjusted when the keyboard appears doesn’t re-adjust when you navigate back and the keyboard’s not there.
One way round the bug is to adjust the background’s idea of what the safe area is, by telling it to always reclaim the keyboard space:
.background(
Color.gray
.ignoresSafeArea(.keyboard)
)
Because you’re only adjusting the safe area for the background, the rest of your view should continue to behave as before. That means that it’s still elevated to accommodate the (missing) keyboard’s space requirement, but it’s less obvious.
I have a small HStack with Text and a Button. This is limited with maxWidth: 200
import SwiftUI
struct ContentView: View {
var body: some View {
HStack {
Text("Some Text")
.frame(maxWidth: .infinity)
Button(action: {}, label: {
Text("A Very much to long button Text with more Text")
.truncationMode(.middle)
})
}.frame(maxWidth: 200)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
This ends up scaling the button even beyond the borders of the HStack.
I do not want to hardcode a width with .frame(maxWidth: 50 on the Buttons Label Text.
It should just take as much space as possible, after that truncating the text (.truncationMode)
How can this be done without GeometryReader so that the result looks like:
Update
As suggested, XCode is checked latest 13.2 on macOS 11.6
Seems to be related to known issues with macOS.
Only solution is, to create a custom ButtonStyle and apply the necessary restrictions there:
struct MacOSFixedButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.truncationMode(.middle)
.lineLimit(1)
}
}
extension View {
func fixedMacOSButton(
) -> some View {
self.buttonStyle(
MacOSFixedButtonStyle()
)
}
}
Applied via:
Button("to long to read it and to put it in a view", action: {})
.fixedMacOSButton()
I'm trying to have a series of favicons downloaded from the internet, and then inserted in a squared-shaped frame. However, they have different sizes, and nor with scaledToFit() or scaledToFill() they seem to fix the issue.
Here's the code:
import SwiftUI
struct ContentView: View {
var websites = ["https://www.reddit.com/favicon.ico", "https://www.facebook.com/favicon.ico", "https://www.instagram.com/favicon.ico", "https://www.google.com/favicon.ico", "https://www.netflix.com/favicon.ico", "https://www.amazon.com/favicon.ico"]
var body: some View {
NavigationView {
Form {
ForEach(websites, id: \.self) { wbs in
Image(uiImage: try! UIImage(withContentsOfUrl: URL(string: wbs)!)!)
.frame(width: 40, height: 40, alignment: .center)
.scaledToFit()
.clipShape(RoundedRectangle(cornerRadius: 10))
.overlay(RoundedRectangle(cornerRadius: 10)
.strokeBorder(Color.gray, lineWidth: 1.0)
.foregroundColor(.clear))
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
extension UIImage {
convenience init?(withContentsOfUrl url: URL) throws {
let imageData = try Data(contentsOf: url)
self.init(data: imageData)
}
}
What I'd like to achieve is that all icons fill the frame the same way. For example, in the screenshot I attached, the favicons of Reddit and Instagram look good, while Facebook is too small and Amazon or Netflix are too big.
Thanks to everyone!
Add the
.resizable()
Modifier to Image
I have a problem related on my List view. The question is simple: how can I get rid of that wierd gray rectangle showing on top of the TabBar? I didn't code that, I just implemented a controller with a List and NavigationBar and then it showed that thing.
For more clear explanation I post the images:
ItemRow.swift code:
import SwiftUI
struct ItemRow: View {
static let colors: [String: Color] = ["D": .purple, "G": .orange, "N": .red, "S": .yellow, "V": .pink]
var item: MenuItem
var body: some View {
NavigationLink(destination: Text(item.name)) {
HStack {
Image(item.thumbnailImage)
.clipShape(Circle())
.overlay(Circle().stroke(Color("IkeaBlu"), lineWidth: 2))
VStack(alignment: .leading){
Text(item.name)
.font(.headline)
Text("€ \(item.price)")
}.layoutPriority(1)
Spacer()
ForEach(item.restrictions, id: \.self) { restriction in
Text(restriction)
.font(.caption)
.fontWeight(.black)
.padding(5)
.background(Self.colors[restriction, default: .black])
.clipShape(Circle())
.foregroundColor(.white)
}
}
}
}
}
struct ItemRow_Previews: PreviewProvider {
static var previews: some View {
ItemRow(item: MenuItem.example)
}
}
thanks a lot for the help
Remove the marked part of hack from TabBar view and that glitch will go.
Tested with Xcode 11.4 / iOS 13.4
} .onAppear {
// UITabBar.appearance().isTranslucent = false // << this one !!
UITabBar.appearance().barTintColor = UIColor(named: "IkeaBlu")
}.accentColor(Color(.white))
I made a textfield and a securetextfield in SwiftUI but I have no idea how to add in an image into my textfield/secure textfield in SwiftUI. There is not much documentation online for SwiftUI like there was for the older versions of Swift. I also want to shift over the (placeholder/typed in text) over by a designated amount say for example like 30 points to the right. I also was trying out to see if the background color would change from white to red, but as you can see, it is in my code with no effect on the UI.
Note:I have the GeometryReader called earlier in my code as well as the #state variables for the username and the password.
My goal is to have it look like this , right now it looks like this
VStack (spacing: deviceSize.size.height * (50/812)) {
TextField ("Username", text: self.$username)
.foregroundColor(.black)//text color when you type
.accentColor(.blue)//cursor color
.background(Color(.red))//????
.textFieldStyle(RoundedBorderTextFieldStyle())
.cornerRadius(50)
// .border(Color.white)
//.font(.title)
SecureField ("Password", text: self.$password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.cornerRadius(50)
}
.padding(.init(top: 0, leading: deviceSize.size.width * (38/375), bottom: 0, trailing: deviceSize.size.width * (38/375)))
The easiest way to achieve such a design would be to place the Image and TextField in a HStack and give it one Rounded background. It is slightly more complicated with the password field as it needs an extra Button, and when you hide/show the password you need to change between TextField and SecureField. Here is my take on it:
struct ContentView: View {
#State private var username = ""
#State private var password = ""
#State private var showPassword = false
var body: some View {
ZStack {
Color.blue
VStack {
HStack {
Image(systemName: "person")
.foregroundColor(.secondary)
TextField("Username",
text: $username)
} .padding()
.background(Capsule().fill(Color.white))
HStack {
Image(systemName: "lock")
.foregroundColor(.secondary)
if showPassword {
TextField("Password",
text: $password)
} else {
SecureField("Password",
text: $password)
}
Button(action: { self.showPassword.toggle()}) {
Image(systemName: "eye")
.foregroundColor(.secondary)
}
} .padding()
.background(Capsule().fill(Color.white))
} .padding()
}
}
}
I'm really new to SwiftUI, but I found a workaround for this that I hope doesn't cause any issues in the future or it will be a big lesson learned. If anyone has any suggestion I'd appreciate it too! =]
I embedded the TextField and the image in a ZStack and I put the image inside a View and gave the view a padding.
struct FormInputBox: View {
#State private var text: String = ""
#State private var textFieldState: TextFieldState = .empty
private var textFieldType: TextFieldType
private var textViewPlaceholder = ""
init(placeholder: String,
textFieldType: TextFieldType) {
self.textViewPlaceholder = placeholder
self.textFieldType = textFieldType
}
var body: some View {
ZStack(alignment: Alignment(horizontal: .trailing, vertical: .center), content: {
TextField(textViewPlaceholder, text: $text)
.textFieldStyle(MyTextFieldStyle(textFieldState: $textFieldState))
AnyView(
Image("tick")
.resizable()
.frame(width: 20, height: 20, alignment: .leading)
)
.padding(32)
})
}
I have created a reusable SwiftUI Textfield named ASTextField which works similar to the textField in UIKit, where you can add the leftView and rightView of the textField and can handle the events related them.
You can find the implementation of this at gist.
This the way you can consume it:-
struct ContentView : View , ASTextFieldDelegate {
let leftImage = UIImage(systemName: "calendar")
let rightImage = UIImage(systemName: "eye")
let rightImage1 = UIImage(systemName: "trash")
#State var text : String? = "with simple binding"
#State var text1 : String? = "with closure for right item"
#State var text2 : String? = "for secure entry"
var body: some View {
VStack {
Spacer()
ASTextField(text: $text)
Spacer()
ASTextField(rightItem: rightImage1, leftItem: leftImage, handleLeftTap: {
print("right icon tapped.....")
}, delegate: self, text: $text1)
Spacer()
ASTextField(rightItem: rightImage, leftItem: leftImage, isSecuredEntry: true, delegate: self, text: $text2)
Spacer()
}
}
}
"Introspect" will work for you
Textfield()
.introspectTextField { textfield in
textfield.rightViewMode = .unlessEditing
textfield.rightView = UIImageView(image: UIImage(named: ImageCatalog.error.content))
}
I am totally newborn toddle in iOS Dev. So i wrote just like this. My apologises in advance if someone will get blind from the ugliness of the written code.
struct ContentView: View {
#State private var nameSearch: String = ""
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 25)
.frame(width: 230, height: 30)
.border(.black, width: 0.2)
.foregroundColor(.white)
HStack {
ZStack {
Image(systemName: "magnifyingglass.circle")
.foregroundColor(.gray)
.frame(width: 10, height: 10, alignment: .leading)
.padding(.trailing, 200)
TextField( "Search", text: $nameSearch)
.frame(width: 180, height: 30)
.padding(.leading, 20 )
}
}
}