How to get rid of the blue selection border around SwiftUI TextFields? - swift

I have created two textfields with the following code:
VStack (spacing: geometry.size.width/48) {
TextField("World Name", text: self.$WorldName)
.font(.system(size: geometry.size.width/28))
.textFieldStyle(PlainTextFieldStyle())
.frame(width: geometry.size.width*0.75)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color.init(white: 0.28))
)
TextField("World Seed", text: self.$WorldSeed)
.font(.system(size: geometry.size.width/28))
.textFieldStyle(PlainTextFieldStyle())
.frame(width: geometry.size.width*0.75)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color.init(white: 0.28))
)
Button (action: {
withAnimation {
self.back.toggle()
}
// Is there a way to "deselect" any textfields here
}){
Text("Back")
}
}
Why is it when I click on one, there is a blue border that does not fade out with the animation, and how can I remove it? This question is specific, and I have provided code, and necessary details, I don't see why it should be too hard to answer.
So in summarized terms, I need to know:
How to get rid of this blue selection border
Or
How to immediately deselect the text field within the button's action,
Get the border to properly line up with the TextField if I apply a padding or round corners.
The only blue in this picture is the border I am referring to
As shown in this screenshot, the textfield is round, but the selection border does not get round corners to reflect the rounded rectangle shape of the entry
The blue border does not fit the padding
I added a padding like this .padding([.leading, .trailing], 6)

You can remove the blue border (which appears on macos even when using PlainTextFieldStyle) by extending NSTextField like so:
extension NSTextField {
open override var focusRingType: NSFocusRingType {
get { .none }
set { }
}
}
See Apple Developer Forum answer here

I don't know which blue border are you referring to, if you are referring to blue border for textfield, there is no blue border beacuse you have given a PlainTextFieldStyle
To deselect the textfield
UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.endEditing(true)
To have a rounded textfield with padding
ZStack {
Rectangle()
.foregroundColor(.clear)
.overlay(RoundedRectangle(cornerRadius: 6).stroke(Color("appcolor").opacity(0.5), lineWidth: 1))
TextField("Enter some text", text: $worldName)
.padding([.leading, .trailing], 6)
}.frame(height: 42)
.padding([.leading, .trailing], 10)

Related

How to keep an item exactly in the center of an HStack with other items in the HStack

I have two items in an HStack. I want one of them to be perfectly horizontally centered and the other to be on the left side (have an alignment of .leading). Here is my code so far:
HStack {
Text("1")
.frame(alignment: .leading)
Text("Hello")
.frame(alignment: .center)
}
I have figured out that the .overlay method works. However, I still want Text("Hello") to be aware of the position of Text("1") so that if Text("Hello") were a longer string, it would know not to cover up Text("1"), which is exactly what happens when the .overlay function is used. So I'm wondering if there are any other solutions.
You can add one more Text view inside HStack as hidden which have the same content as your left align text view along with Spacer. Something like this.
HStack {
Text("1")
Spacer()
Text("Good Morning, Hello World. This is long message")
.multilineTextAlignment(.center)
Spacer()
Text("1") // Set the same content as left aligned text view
.hidden()
}
.padding(.horizontal)
Preview
Not sure if it's the best way, but you can use a GeometryReader to get the screen width and skip the first half.
To place the text exactly in the center, you should also calculate the width of the text. you can use a simple extension to get the size of your text:
extension String {
public func size(withFont font: UIFont) -> CGSize {
(self as NSString).size(withAttributes: [.font: font])
}
}
Here is the example code:
GeometryReader { geo in
HStack {
Spacer()
.frame(width: (geo.size.width - "center".size(withFont: UIFont.systemFont(ofSize: 18)).width) / 2)
HStack {
Text("center")
Text("another")
}
}
}

SwiftUI: Decide which content the keyboard overlaps

I'm trying to find a way to mark which content is overlapped by the keyboard that pops up when a TextField is focused.
Consider the minimal example below:
VStack {
TextField(text: $text) {}
Spacer()
Circle()
.frame(width: 100, height: 100)
}
I'm looking for a custom modifier that I could apply to the Circle. This would dictate whether the keyboard should push the Circle up above the keyboard, as is default, or if the keyboard should overlap the Circle (I'm not sure how to get the keyboard to simply overlap a view, either).
So far I've found primarily Objective-C solutions... Are there any SwiftUI ways to go about this? Thank you for the help!
If I understood correctly your goal then you don't need custom modifier - there is standard modifier, which you can either add or remove, or use with some condition.
VStack {
TextField(text: $text) {}
.textFieldStyle(.roundedBorder)
VStack {
Spacer()
Circle()
.frame(width: 100, height: 100)
}
.ignoresSafeArea(.keyboard, edges: .bottom) // << here !!
//.ignoresSafeArea(yourFlag ? .keyboard : .container, edges: .bottom) // << alternate
}

SwiftUI: Rounded Rectangle Overlay Corners Cut Off

I'm trying to have a consistent-width broder with an overlay, and I keep getting the wrong result. My overlay looks like this:
With this code:
VStack {
HStack {
Text("Test")
}
HStack {
Text("test2")
}
}
.padding()
.frame(width: UIScreen.main.bounds.width*0.95)
.frame(minHeight: 50)
.overlay (
RoundedRectangle(cornerRadius: 20)
.stroke(RandomColor(), lineWidth: 3)
)
As you can see the corners are thicker than all other parts of the overlay. How can I fix this?
The thing you are missing is the difference between stroke and strokeBorder, if you changed your code to strokeBorder, it help you.
RoundedRectangle(cornerRadius: 20)
.strokeBorder(RandomColor(), lineWidth: 3)
The lineWidth makes it stretch beyond its bounds slightly. You can balance this with inset(by:) to keep it inside the original frame:
RoundedRectangle(cornerRadius: 20)
.inset(by: 3)
.stroke(RandomColor(), lineWidth: 3)
Note: you may only need to inset by 2 -- haven't done enough experimentation to see what the exact number is

Round Specific Corners of Stroke/Border SwiftUI

I am working on a SwiftUI project where I need a view to have a border with only some of the corners rounded (for instance, the top left and top right).
I added a RoundedRectangle with a stroke and was able to have all of the corners rounded. However, I need only some of the corners to be rounded and I couldn't figure out a way to do that.
This is the code I had to add a RoundedRectangle:
.overlay(
RoundedRectangle(cornerRadius: 20)
.stroke(Color.gray, lineWidth: 1)
)
To make only specific corners rounded, I looked at this Stackoverflow post: Round Specific Corners SwiftUI. However, I would have to get rid of the Rounded Rectangle (because it rounds all corners). I would have to use a normal border instead. But, with a normal border, it will cut out a piece of the border when rounding corners and trying any of the answers provided.
This is what I would ideally want it to look like (this is from an example from Bootstrap - we are rebuilding a website as an app):
Thank you!
Here's an alternative / easier way to recreate this. Add a white background to each of the rows and add a single gray background color behind them. Add spacing between the rows to let the gray background color appear like a divider between them. Then just add a rectangle overlay to the entire view, like you already had in your code!
struct CornerView: View {
var body: some View {
VStack(spacing: 1) {
ForEach(0..<5) { index in
Text("Item \(index)")
.frame(maxWidth: .infinity)
.frame(height: 55)
.background(Color.white)
}
}
.background(Color.gray)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color.gray, lineWidth: 1)
)
.padding()
}
}
struct CornerView_Previews: PreviewProvider {
static var previews: some View {
CornerView2()
}
}

SwiftUI changing the color of clear part inside of SF Symbol

I am trying to change the color of clear(transparent) part inside of a SF Symbol called delete.left.fill. So far I've tried is as follows
Button(action: { return }, label: {
Image(systemName: "delete.left.fill")
.background(Color.black)
//.accentColor(.black)
.font(.system(size: self.fontSize*0.75))
})
.frame(width: self.width, height: self.width)
.foregroundColor(.lightGray)
//.background(Color.black)
When I run the code as above, the result is like
.
At first, the xinside of the symbol was the same color as background. I want it to make black.
I tried to set the backgroundColor of the Button and it made
whole Button black.
I tried to set accentColor of the Image to
black. Nothing changed.
I tried to set backgroundColor of the
Image to black. The result can be seen in the image.
The question is, is there a way to make just that x, inside the symbol, black programmatically?
You could mask the background and apply a custom style:
struct MyButtonStyle: ButtonStyle {
public func makeBody(configuration: MyButtonStyle.Configuration) -> some View {
configuration.label
.compositingGroup()
.opacity(configuration.isPressed ? 0.5 : 1.0)
}
}
Button(action: {}) {
Image(systemName: "delete.left.fill")
.foregroundColor(.green)
.background(
Color.black.mask(Circle())
)
}.buttonStyle(MyButtonStyle())
The circle may not fit to any usage, but for this image it works okay:
As he warned with the circle, #Faruk's solution didn't work for me with the exclamationmark.triangle.fill
I created a ZStack with the fill and unfill versions to create a yellow triangle with a black exclamation point and a black border:
ZStack{
Image(systemName: "exclamationmark.triangle")
.foregroundColor(Color.black)
.scaleEffect(1.1)
Image(systemName: "exclamationmark.triangle.fill")
.foregroundColor(Color.yellow)
}
I've only tried on couple of simulators, but it looks nice on iPadPro and iPad Mini
as of iOS 15 you can simply achieve that with .foregroundStyle(.red, .blue)