admin管理员组文章数量:1278720
Given the following code:
import SwiftUI
struct HomeScreenCounterView: View {
private let value: Int
private let title: String
private let emptyDescription: String
init(value: Int, title: String, emptyDescription: String) {
self.value = value
self.title = title
self.emptyDescription = emptyDescription
}
var body: some View {
VStack {
Text("Messages")
.font(.fontTextLBold)
Text("No new messages")
.font(.fontTextSRegular)
}
.padding()
.clipShape(RoundedRectangle(cornerRadius: 16))
}
}
#Preview {
HomeScreenCounterView(value: 0,
title: "Messages",
emptyDescription: "No new messages")
.foregroundStyle(Color.red)
.background(Color.blue)
}
I get the following result:
Notice, how the text color in both labels has been changed to red.
While the background is correctly displayed as blue, it is obviously not clipped, as the clipping operator has been applied earlier, not later.
What would be the best/the most elegant way to have a background color modifier, similarly to how the other SwiftUI components work?
One of the solutions I am thinking of, and it's obviously a working solution, is to add an initializer parameter:
init(value: Int, title: String, emptyDescription: String, backgroundColor: Color) {
And then using that value to set the background color just after padding
:
.padding()
.background(backgroundColor)
.clipShape(RoundedRectangle(cornerRadius: 16))
But is there a better way?
This is how I'd like the end result to look like:
Given the following code:
import SwiftUI
struct HomeScreenCounterView: View {
private let value: Int
private let title: String
private let emptyDescription: String
init(value: Int, title: String, emptyDescription: String) {
self.value = value
self.title = title
self.emptyDescription = emptyDescription
}
var body: some View {
VStack {
Text("Messages")
.font(.fontTextLBold)
Text("No new messages")
.font(.fontTextSRegular)
}
.padding()
.clipShape(RoundedRectangle(cornerRadius: 16))
}
}
#Preview {
HomeScreenCounterView(value: 0,
title: "Messages",
emptyDescription: "No new messages")
.foregroundStyle(Color.red)
.background(Color.blue)
}
I get the following result:
Notice, how the text color in both labels has been changed to red.
While the background is correctly displayed as blue, it is obviously not clipped, as the clipping operator has been applied earlier, not later.
What would be the best/the most elegant way to have a background color modifier, similarly to how the other SwiftUI components work?
One of the solutions I am thinking of, and it's obviously a working solution, is to add an initializer parameter:
init(value: Int, title: String, emptyDescription: String, backgroundColor: Color) {
And then using that value to set the background color just after padding
:
.padding()
.background(backgroundColor)
.clipShape(RoundedRectangle(cornerRadius: 16))
But is there a better way?
This is how I'd like the end result to look like:
Share Improve this question asked Feb 25 at 10:10 Richard TopchiiRichard Topchii 8,2159 gold badges60 silver badges129 bronze badges3 Answers
Reset to default 2Use backgroundStyle()
to change the style that the .background
shape style will resolve to. This also sets the backgroundStyle
environment value.
// Preview
HomeScreenCounterView(value: 0,
title: "Messages",
emptyDescription: "No new messages")
.foregroundStyle(Color.red)
.backgroundStyle(.blue) // <-----
// HomeScreenCounterView.body
VStack {
Text("Messages")
Text("No new messages")
}
.padding()
.background(.background) // <-----
.clipShape(RoundedRectangle(cornerRadius: 16))
Alternatively, you can write your own environment value to store the background style, in case you don't want to affect other views that might be using the .background
shape style.
extension EnvironmentValues {
@Entry var myBackground: AnyShapeStyle = AnyShapeStyle(.background)
}
// a view modifier that sets this environment value
extension View {
func myBackground<S: ShapeStyle>(_ style: S) -> some View {
environment(\.myBackground, AnyShapeStyle(style))
}
}
You can then write your own ShapeStyle
that resolves to this environment value.
struct MyBackgroundStyle: ShapeStyle {
func resolve(in environment: EnvironmentValues) -> AnyShapeStyle {
environment.myBackground
}
}
extension ShapeStyle where Self == MyBackgroundStyle {
static var myBackground: MyBackgroundStyle { .init() }
}
Usage:
// HomeScreenCounterView.body
VStack {
Text("Messages")
Text("No new messages")
}
.padding()
.background(.myBackground) // <-----
.clipShape(RoundedRectangle(cornerRadius: 16))
// Preview
HomeScreenCounterView(value: 0,
title: "Messages",
emptyDescription: "No new messages")
.foregroundStyle(Color.red)
.myBackground(.blue) // <-----
Before iOS 17, you cannot create your own ShapeStyle
, so you would need a ViewModifier
instead of a custom ShapeStyle
.
struct MyBackgroundModifier: ViewModifier {
@Environment(\.myBackground) var myBackground
func body(content: Content) -> some View {
content.background(myBackground)
}
}
extension View {
func useMyBackground() -> some View {
modifier(MyBackgroundModifier())
}
}
You'd then replace .background(.myBackground)
with .useMyBackground()
.
You could consider using a semantic shape style for filling the background inside the view. The obvious choice would be .background
, but you could also use one of the other semantic or hierarachical styles such as .secondary
. The actual color can then be set from a parent view:
// HomeScreenCounterView
VStack {
// ...
}
.padding()
.background(.background, in: .rect(cornerRadius: 16)) // or, say, .secondary
// Parent
HomeScreenCounterView(
// ...
)
.foregroundStyle(.red)
// .foregroundStyle(.red, .blue) // for setting .blue as secondary
.backgroundStyle(.blue)
You can use the second argument of the background
modifier to put it in
any shape you like:
#Preview {
HomeScreenCounterView(value: 0, title: "Messages", emptyDescription: "No new messages")
.foregroundStyle(Color.red)
.background(.blue, in: .rect(cornerRadius: 16)) //
本文标签:
iosSwiftUI adjust background externallysimilar to the foregroundStyleStack Overflow
版权声明:本文标题:ios - SwiftUI adjust background externally, similar to the foregroundStyle - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人,
转载请联系作者并注明出处:http://www.betaflare.com/web/1741213053a2359510.html,
本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论