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.
Related
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)
I'd like to make a 2px border from a view, but the border only accepts a ShapeStyle. I'm trying to do something like:
let specialRadialGradient = GeometryReader { geometry in
RadialGradient(
gradient: Gradient(
stops: [
.init(color: Color("gradient1").opacity(0.5), location: 0),
.init(color: Color("gradient2").opacity(0.5), location: 1)
]
),
center: .init(x: 0.1432, y: 0.7254
startRadius: .zero,
endRadius: geometry.size.width * 0.75
)
.background(Color.brandPrimary)
}
Text("Abc")
.frame(maxWidth: .infinity)
.padding()
.border(specialRadialGradient, 2)
However, since the specialRadialGradient view is wrapped in a GeometryReader to handle the radial gradient properly in all ratio sizes, it doesn't compile. How can I cut out a 2px border out of specialRadialGradient and apply it to the background of the text?
Instead of border it can be done with composition of background and blending mode.
Here is a demo of possible approach. Tested with Xcode 14 / iOS 16
*(gradient colours just replicated for demo)
let borderWidth = 2.0
Text("Abc")
.frame(maxWidth: .infinity)
.padding()
.background(
specialRadialGradient
.overlay(Rectangle().padding(borderWidth) // << here !!
.blendMode(.destinationOut))
.compositingGroup() // << important !!
)
Test code on GitHub
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.
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().
For some reason the Text() view that I create sometimes doesn't fit the string correctly in its frame and instead draws the ellipsis -- while I am not explicitly defining the frame of the view. So I would like to "expand" the frame by a dx/dy amount in the x/y directions -- is there a view modifier that I can use for that? ex. Text(" Jx3 ").expand(dx: +4, dy: 0) Or maybe I'm not supposed to use extra space in the string, but then the background shape is too narrow.
viewForPoints(displayHistory[index].displayPoints)
.overlay(
Text(" \(displayHistory[index].abbreviation) ")
.foregroundColor(.gray)
.font(FONTO)
.offset(x: +8, y: +14)
.background(
Capsule()
.fill(Color.white)
.offset(x: +8, y: +14)
)
)
Try to use fixed size, as
.overlay(
Text(" \(displayHistory[index].abbreviation) ")
.fixedSize()
)
Tested & works with some replicated code with Xcode 11.2 / iOS 13.2
Note: overlay uses same frame as its owner, so probably it worth considering ZStack for your case instead.