在 SwiftUI 的 TabView 上方添加阴影 设置背景图片设置shadowImage结果

问题描述

我正在尝试在 SwiftUI 中实现 TabView,它具有与屏幕背景相同的颜色,但在其上方还有一个 阴影,如下图所示:

enter image description here

到目前为止,我已经能够正确显示颜色,但我不知道如何添加阴影。这是我的代码

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 {} 内的 case,并且 TabView() 包含一些 Button 元素,这些元素将通过使用 {{ 1}}。因此,您可以通过修改 @State var tabIdx 语句来调整您的操作。

在每个按钮之后用这个语句设置活动颜色:

self.tabIdx = <yourtab>

在这里,您可以将 .foregroundColor(self.tabIdx == .borrow ? .purple : .secondary) 更改为适合您的任何内容。

您可以看到在 .purple 上,ContentView 块捕获了 SubView。我在这里放置了一些 if-else if 元素,例如 Text(),因此您可以通过调用 Text("Borrow") 之类的东西或您拥有的任何东西来替换它们。

当我从 BorrowView() 中调用 TabView 时,我已经添加了阴影,但是您甚至可以在 {{1} 的 ContentView 之后添加 .shadow(radius: 10) } 本身。

这将是最终输出

enter image description here

,

简答

我找到了解决方案。您可以创建自己的阴影图像并将其添加到 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

设置shadowImage

我想以编程方式生成阴影图像。为此,我创建了 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

结果

enter image description here

,

尝试设置 appearance.shadowColor

init() {
    let appearance = UITabBarAppearance()
    appearance.configureWithTransparentBackground()
    appearance.shadowColor = .gray /// here!
    UITabBar.appearance().standardAppearance = appearance
}

结果:

Thin gray shadow above tab bar

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...