ios - 如何在 SwiftUI 的 TabView 中添加底部曲线?

标签 ios swiftui curve tabview tabitem

我只想在我的 tabView 中心有一个 Bottom 曲线,但我无法访问 tabView 形状属性。

Final Image

这就是我想要的。

注意:

The curve should always remain in center. And the items should swap, which is already achieved in the given code.

import SwiftUI

struct DashboardTabBarView: View {

@State private var selection: String = "home"

struct Item {
    let title: String
    let color: Color
    let icon: String
}

@State var items = [
    Item(title: "cart", color: .red, icon: "cart"),
    Item(title: "home", color: .blue, icon: "house"),
    Item(title: "car", color: .green, icon: "car"),
]

var body: some View {

    TabView(selection: $selection) {
        ForEach(items, id: \.title) { item in // << dynamically !!
            item.color
                .tabItem {
                    Image(systemName: item.icon)
                    Text(item.title)
                }
        }
    }
    .onChange(of: selection) { title in // << reorder with centered item
        let target = 1
        if var i = items.firstIndex(where: { $0.title == title }) {
            if i > target {
                i += 1
            }
            items.move(fromOffsets: IndexSet(integer: target), toOffset: i)
        }
    }
}
}

最佳答案

好的,实际上我们需要在这里解决两个问题,首先 - 找到标签栏的高度,其次 - 正确地将 View 自定义 View 与标准标签栏上代表的所选项目对齐。其他一切都是机制

这是简化的演示。已使用 Xcode 14/iOS 16 进行测试。

demo

主要部分:

  • 问题#1 的可能解决方案
struct TabContent<V: View>: View {
    @Binding var height: CGFloat
    @ViewBuilder var content: () -> V

    var body: some View {
        GeometryReader { gp in  // << read bottom edge !!
            content()
                .onAppear {
                    height = gp.safeAreaInsets.bottom
                }
                .onChange(of: gp.size) { _ in
                    height = gp.safeAreaInsets.bottom
                }
        }
    }
}
  • 问题#2 的可能解决方案
    // Just put customisation in z-ordered over TabView
    ZStack(alignment: .bottom) {
        TabView(selection: $selection) {
            // .. content here
        }

        TabSelection(height: tbHeight, item: selected)
    }


struct TabSelection: View {
    let height: CGFloat
    let item: Item
    
    var body: some View {
        VStack {
            Spacer()
            Curve()    // put curve over tab bar !!
                .frame(maxWidth: .infinity, maxHeight: height)
                .foregroundColor(item.color)
        }
        .ignoresSafeArea()   // << push to bottom !!
        .overlay(
            // Draw overlay
            Circle().foregroundColor(.black)
                .frame(height: height).aspectRatio(contentMode: .fit)
                .shadow(radius: 4)
                .overlay(Image(systemName: item.icon)
                    .font(.title)
                    .foregroundColor(.white))
            , alignment: .bottom)
    }
}

Test module is here

关于ios - 如何在 SwiftUI 的 TabView 中添加底部曲线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73156676/

相关文章:

ios - 如何在没有 NavigationLink 的情况下使用 SwiftUI 推送新的 Root View ?

SwiftUI - IOS 15 - 文本 .mimimumScaleFactor - 始终被应用

javascript - 数据范围紧凑

c++ - 我怎样才能找到曲线上方的区域

ios - 引用 iOS 应用程序的 Xcode 项目中的目录

ios - 无法修改自定义表格 View 单元格属性

iphone - objective-c : for-loop gets slower and slower

ios - 添加一个 UIView 到另一个

ios - 带有系统背景颜色的列表在黑暗模式下变得困惑

iphone - 如何在iPhone上用cocos2d + Box2d创建一个带有曲线的关卡?