Swiftui put border with different radii and stroke the border - swiftui

I need to put a .cornerRadius with different radii for each corner around a view with padding and I need to put an outline around that border. Any ideas?

Text("one possibility")
.font(.title)
.multilineTextAlignment(.center)
.padding(10)
.border(Color.black, width: 2)
.cornerRadius(10, 20, 30, 40)

Related

Shadow of RoundedRectangle is pixelated on edges

Based on some logic we apply shadow for RoundedRectangle which is the element used in the .background property of the whole VStack.
VStack {
...
}
.background(
RoundedRectangle(cornerRadius: 16, style: .continuous)
.foregroundColor(.white)
.shadow(color: .black,
radius: .zero,
x: 4,
y: 4)
)
The pixelated parts appear on the bottom left and right edges as well as the top right corner.
I did try using different kinds of RoundedRectangle styles (both of them .circular & continuous), but nothing really helped.
Thanks in advance.

SwiftUI squared image in a circle

I try to draw a squared Image inside of a Circle to get something like that (without blue square here. It is just to show image squared border):
This code makes squared image over all circle.
ZStack() {
Circle()
.fill(.orange)
Image(systemName: "trash")
.resizable()
.foregroundColor(.blue)
.background(.orange)
}
This code makes a small image on the circle or no circle at all:
ZStack() {
Circle()
.fill(.orange)
Image(systemName: "trash")
.foregroundColor(.blue)
.background(.orange)
}
I try to find a solution to have squared image inside the circle. It should not goes outside of it.
Maybe, I would also need a small margin between image and circle's border.
Is there a way to do that easily? Or I have to use math to get circle border or something like that?
Asperi just beat me to it, but this view will just take an icon name and a radius and return a squared icon perfectly in a circle:
struct ImageOnCircle: View {
let icon: String
let radius: CGFloat
var squareSide: CGFloat {
2.0.squareRoot() * radius
}
var body: some View {
ZStack {
Circle()
.fill(.orange)
.frame(width: radius * 2, height: radius * 2)
Image(systemName: icon)
.resizable()
.aspectRatio(1.0, contentMode: .fit)
.frame(width: squareSide, height: squareSide)
.foregroundColor(.blue)
}
}
}
Use:
ImageOnCircle(icon: "trash", radius: 150)
Here is a demo of possible approach - use overlay + geometry reader to calculate internal rectangle where image is injected.
Tested with Xcode 13 / iOS 15 (blue rect is of Preview one for selected image)
Circle()
.fill(.orange)
.overlay(GeometryReader {
let side = sqrt($0.size.width * $0.size.width / 2)
VStack {
Rectangle().foregroundColor(.clear)
.frame(width: side, height: side)
.overlay(
Image(systemName: "trash")
.resizable()
.foregroundColor(.blue)
)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
})
.frame(width: 100, height: 100)

CornerRadius issue with GeometryReader in SwiftUI

I have a small red Rec inside GeometryReader, if I use cornerRadius on GeometryReader it will going crop the Rec, which I do not want it. See the deference in photos:
struct ContentView: View {
var body: some View {
GeometryReader { _ in
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 100, alignment: .center)
.position(x: 0, y: 0)
}
.background(Color.yellow)
.frame(width: 200, height: 300, alignment: .center)
.cornerRadius(10) // <<: Here try comment and uncomment it to see the result!
}
}
without cornerRadius:
with cornerRadius:
If you only want the yellow to have the corner radius and to not crop the red square, give the corner radius to only the background:
.background(
Color.yellow
.cornerRadius(10)
)
If you want the red square to have a corner radius as well but not be cropped, give it a corner radius as well:
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 100, alignment: .center)
.cornerRadius(10)
.position(x: 0, y: 0)
Giving the GeometryReader itself a corner radius is not something that I would expect to have straightforward results, since the GeometryReader itself is not rendered per say (or at least rendered like we normally think of visual components), but as we can see from your example, it's basically treated like a container view -- giving it a corner radius ends up cropping out everything outside the bounds of it's content minus the corner radius.

SwiftUI: vertical align dynamic sized Rectangle with Spacer in SwiftUI

It seems there is a potential bug in SwiftUI. I am trying to put a rectangle with opacity 0.5 on top of an image.
When I try to fix the transparent rectangle on top, from 100px width, it goes down instead of sticking to the top.
Here is the code:
ZStack {
VStack {
Image("movistar")
.resizable(capInsets: EdgeInsets(), resizingMode: .stretch)
.scaledToFit()
.cornerRadius(8)
.padding(15)
.frame(minWidth: Global.SCREEN_WIDTH)
}
VStack {
HStack {
Rectangle()
.fill(Color(red: 0, green: 0, blue: 0, opacity: 0.5))
.frame(width: 110, height: Global.SCREEN_WIDTH / 4)
}
Spacer()
}
.scaledToFit()
.cornerRadius(8)
.padding(15)
.frame(width: Global.SCREEN_WIDTH, height: Global.SCREEN_WIDTH)
There is no bug here. If you add a .background to all of your layers, you will see that because of the way you set up the view (ie. Spacer, scaledToFit, etc.) the actual frames of the views are not necessarily the edges of the image. You also have not set the alignment of any of the Stacks or Frames.
There are many ways to do what you are trying to do, but I believe this is the simplest:
var body: some View {
Image("movistar")
.resizable(capInsets: EdgeInsets(), resizingMode: .stretch)
.scaledToFit()
.cornerRadius(8)
.frame(minWidth: UIScreen.main.bounds.width)
.overlay(
Rectangle()
.fill(Color(red: 0, green: 0, blue: 0, opacity: 0.5))
.frame(width: 110, height: UIScreen.main.bounds.width / 4)
, alignment: .top
)
}
Finally got into a solution: .scaleToFit() was messing with the VStack(). After deleting, it worked perfectly. I also got rid of the HStack().

SwiftUI: Images in a List are no longer center after adding a .frame maxHeight

I'm displaying a List of images, which works fine. They are all centered in the list, but when I add a maxHeight the images move to leading instead of center, so I set the alignment to .center, but that doesn't seem to do anything.
NavigationView {
List(words, id: \.self) { word in
NavigationLink(destination: testView(word: word)) {
Image(word.imageName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame( maxHeight: 200, alignment: .center )
}
}
}
Has anyone else had this problem and know how to solve it?
Thank you
This is the feedback I received from Apple:
Engineering has provided the following information regarding this
issue:
You need the frame to have an infinite width. This is a layout bug.
Please try using a frame with infinite width.
Setting the maxWidth to .infinity did provide a work around for the bug.
For example:
.frame(maxWidth: .infinity, maxHeight: 250)