在 SwiftUI 的 TabView 上方添加阴影
Add shadow above SwiftUI's TabView
我正在尝试在 SwiftUI 中实现 TabView,它具有与屏幕背景相同的颜色,但在其上方也有一个 阴影,如下图所示:
到目前为止我已经能够正确显示颜色,但我不知道如何添加阴影。这是我的代码:
struct ContentView: View {
init() {
let appearance = UITabBarAppearance()
appearance.configureWithTransparentBackground()
UITabBar.appearance().standardAppearance = appearance
}
var body: some View {
TabView {
Text("First View")
.tabItem {
Image(systemName: "square.and.arrow.down")
Text("First")
}
Text("Second View")
.tabItem {
Image(systemName: "square.and.arrow.up")
Text("Second")
}
}
}
}
有人知道怎么做吗?非常感谢您的帮助:)
为了完全实现您的愿望,您最好的选择是创建自定义 TabView
。
事实上,在 SwiftUI 中,您可以使用 UITabBarAppearance().shadowColor
,但除了在 TabView 本身的顶部绘制一条 2px 的线外,这不会做太多事情。
相反,使用以下代码,您可以创建自定义 TabView
并实现所需的图形效果。
import SwiftUI
enum Tab {
case borrow,ret,device,you
}
struct TabView: View {
@Binding var tabIdx: Tab
var body: some View {
HStack {
Group {
Spacer()
Button (action: {
self.tabIdx = .borrow
}) {
VStack{
Image(systemName: "arrow.down.circle")
Text("Borrow")
.font(.system(size: 10))
}
}
.foregroundColor(self.tabIdx == .borrow ? .purple : .secondary)
Spacer()
Button (action: {
self.tabIdx = .ret
}) {
VStack{
Image(systemName: "arrow.up.circle")
Text("Return")
.font(.system(size: 10))
}
}
.foregroundColor(self.tabIdx == .ret ? .purple : .secondary)
Spacer()
Button (action: {
self.tabIdx = .device
}) {
VStack{
Image(systemName: "safari")
Text("Device")
.font(.system(size: 10))
}
}
.foregroundColor(self.tabIdx == .device ? .purple : .secondary)
Spacer()
Button (action: {
self.tabIdx = .you
}) {
VStack{
Image(systemName: "person.circle")
Text("You")
.font(.system(size: 10))
}
}
.foregroundColor(self.tabIdx == .you ? .purple : .secondary)
Spacer()
}
}
.padding(.bottom, 30)
.padding(.top, 10)
.background(Color(red: 0.95, green: 0.95, blue: 0.95))
.font(.system(size: 30))
.frame(height: 80)
}
}
struct ContentView: View {
@State var tabIdx: Tab = .borrow
var body: some View {
NavigationView {
VStack(spacing: 20) {
Spacer()
if tabIdx == .borrow {
Text("Borrow")
} else if tabIdx == .ret {
Text("Return")
} else if tabIdx == .device {
Text("Device")
} else if tabIdx == .you {
Text("You")
}
Spacer(minLength: 0)
TabView(tabIdx: self.$tabIdx)
.shadow(radius: 10)
}
.ignoresSafeArea()
}
}
}
请记住,当您执行此操作时,所有选项卡都指定为 enum Tab {}
内的大小写,并且 TabView()
包含一些 Button
元素,这将通过使用@State var tabIdx
。所以你可以通过修改self.tabIdx = <yourtab>
语句来调整你的动作。
活动颜色在每个按钮后使用此语句设置:
.foregroundColor(self.tabIdx == .borrow ? .purple : .secondary)
在这里你可以把.purple
改成适合你的。
您可以看到在 ContentView
上,if-else if
块捕获了 SubView。我在这里放置了一些 Text()
元素,例如 Text("Borrow")
,因此您可以通过调用 BorrowView()
或任何您拥有的东西来替换它们。
我在 ContentView
中调用 TabView
时添加了阴影,但您甚至可以在 HStack
之后添加 .shadow(radius: 10)
12=]本身。
这将是最终输出:
简答
我找到了解决办法。您可以创建自己的阴影图像并将其添加到 UITabBar 外观,如下所示:
// load your custom shadow image
let shadowImage: UIImage = ...
//you also need to set backgroundImage, without it shadowImage is ignored
UITabBar.appearance().backgroundImage = UIImage()
UITabBar.appearance().shadowImage = shadowImage
更详细的回答
设置背景图片
注意通过设置
UITabBar.appearance().backgroundImage = UIImage()
您将 TabView 设为透明,因此如果您的内容可以在其下方滚动则不太理想。为了克服这个问题,您可以设置 TabView 的颜色。
let appearance = UITabBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = UIColor.systemGray6
UITabBar.appearance().standardAppearance = appearance
设置阴影图像
我想以编程方式生成阴影图像。为此,我创建了 UIImage 的扩展。 (code taken from here)
extension UIImage {
static func gradientImageWithBounds(bounds: CGRect, colors: [CGColor]) -> UIImage {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.colors = colors
UIGraphicsBeginImageContext(gradientLayer.bounds.size)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
最后我将我的 TabView 设计成这样:
let image = UIImage.gradientImageWithBounds(
bounds: CGRect( x: 0, y: 0, width: UIScreen.main.scale, height: 8),
colors: [
UIColor.clear.cgColor,
UIColor.black.withAlphaComponent(0.1).cgColor
]
)
let appearance = UITabBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = UIColor.systemGray6
appearance.backgroundImage = UIImage()
appearance.shadowImage = image
UITabBar.appearance().standardAppearance = appearance
结果
我正在尝试在 SwiftUI 中实现 TabView,它具有与屏幕背景相同的颜色,但在其上方也有一个 阴影,如下图所示:
到目前为止我已经能够正确显示颜色,但我不知道如何添加阴影。这是我的代码:
struct ContentView: View {
init() {
let appearance = UITabBarAppearance()
appearance.configureWithTransparentBackground()
UITabBar.appearance().standardAppearance = appearance
}
var body: some View {
TabView {
Text("First View")
.tabItem {
Image(systemName: "square.and.arrow.down")
Text("First")
}
Text("Second View")
.tabItem {
Image(systemName: "square.and.arrow.up")
Text("Second")
}
}
}
}
有人知道怎么做吗?非常感谢您的帮助:)
为了完全实现您的愿望,您最好的选择是创建自定义 TabView
。
事实上,在 SwiftUI 中,您可以使用 UITabBarAppearance().shadowColor
,但除了在 TabView 本身的顶部绘制一条 2px 的线外,这不会做太多事情。
相反,使用以下代码,您可以创建自定义 TabView
并实现所需的图形效果。
import SwiftUI
enum Tab {
case borrow,ret,device,you
}
struct TabView: View {
@Binding var tabIdx: Tab
var body: some View {
HStack {
Group {
Spacer()
Button (action: {
self.tabIdx = .borrow
}) {
VStack{
Image(systemName: "arrow.down.circle")
Text("Borrow")
.font(.system(size: 10))
}
}
.foregroundColor(self.tabIdx == .borrow ? .purple : .secondary)
Spacer()
Button (action: {
self.tabIdx = .ret
}) {
VStack{
Image(systemName: "arrow.up.circle")
Text("Return")
.font(.system(size: 10))
}
}
.foregroundColor(self.tabIdx == .ret ? .purple : .secondary)
Spacer()
Button (action: {
self.tabIdx = .device
}) {
VStack{
Image(systemName: "safari")
Text("Device")
.font(.system(size: 10))
}
}
.foregroundColor(self.tabIdx == .device ? .purple : .secondary)
Spacer()
Button (action: {
self.tabIdx = .you
}) {
VStack{
Image(systemName: "person.circle")
Text("You")
.font(.system(size: 10))
}
}
.foregroundColor(self.tabIdx == .you ? .purple : .secondary)
Spacer()
}
}
.padding(.bottom, 30)
.padding(.top, 10)
.background(Color(red: 0.95, green: 0.95, blue: 0.95))
.font(.system(size: 30))
.frame(height: 80)
}
}
struct ContentView: View {
@State var tabIdx: Tab = .borrow
var body: some View {
NavigationView {
VStack(spacing: 20) {
Spacer()
if tabIdx == .borrow {
Text("Borrow")
} else if tabIdx == .ret {
Text("Return")
} else if tabIdx == .device {
Text("Device")
} else if tabIdx == .you {
Text("You")
}
Spacer(minLength: 0)
TabView(tabIdx: self.$tabIdx)
.shadow(radius: 10)
}
.ignoresSafeArea()
}
}
}
请记住,当您执行此操作时,所有选项卡都指定为 enum Tab {}
内的大小写,并且 TabView()
包含一些 Button
元素,这将通过使用@State var tabIdx
。所以你可以通过修改self.tabIdx = <yourtab>
语句来调整你的动作。
活动颜色在每个按钮后使用此语句设置:
.foregroundColor(self.tabIdx == .borrow ? .purple : .secondary)
在这里你可以把.purple
改成适合你的。
您可以看到在 ContentView
上,if-else if
块捕获了 SubView。我在这里放置了一些 Text()
元素,例如 Text("Borrow")
,因此您可以通过调用 BorrowView()
或任何您拥有的东西来替换它们。
我在 ContentView
中调用 TabView
时添加了阴影,但您甚至可以在 HStack
之后添加 .shadow(radius: 10)
12=]本身。
这将是最终输出:
简答
我找到了解决办法。您可以创建自己的阴影图像并将其添加到 UITabBar 外观,如下所示:
// load your custom shadow image
let shadowImage: UIImage = ...
//you also need to set backgroundImage, without it shadowImage is ignored
UITabBar.appearance().backgroundImage = UIImage()
UITabBar.appearance().shadowImage = shadowImage
更详细的回答
设置背景图片
注意通过设置
UITabBar.appearance().backgroundImage = UIImage()
您将 TabView 设为透明,因此如果您的内容可以在其下方滚动则不太理想。为了克服这个问题,您可以设置 TabView 的颜色。
let appearance = UITabBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = UIColor.systemGray6
UITabBar.appearance().standardAppearance = appearance
设置阴影图像
我想以编程方式生成阴影图像。为此,我创建了 UIImage 的扩展。 (code taken from here)
extension UIImage {
static func gradientImageWithBounds(bounds: CGRect, colors: [CGColor]) -> UIImage {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.colors = colors
UIGraphicsBeginImageContext(gradientLayer.bounds.size)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
最后我将我的 TabView 设计成这样:
let image = UIImage.gradientImageWithBounds(
bounds: CGRect( x: 0, y: 0, width: UIScreen.main.scale, height: 8),
colors: [
UIColor.clear.cgColor,
UIColor.black.withAlphaComponent(0.1).cgColor
]
)
let appearance = UITabBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = UIColor.systemGray6
appearance.backgroundImage = UIImage()
appearance.shadowImage = image
UITabBar.appearance().standardAppearance = appearance