Joh*_*110 1 tabbar uikit swift swiftui
我正在尝试重现一个“Instagram”,例如tabBar中间有一个“实用程序”按钮,不一定属于tabBar生态系统。
我附上了这个 gif 来显示我所追求的行为。来描述问题。中间的标签栏(黑色加号)是单击一个 ActionSheet,而不是切换视图。
我将如何在 UIKit 中做到这一点只是使用
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
print("Selected item")
}
Run Code Online (Sandbox Code Playgroud)
功能来自UITabBarDelegate. 但显然我们不能在 SwiftUI 中做到这一点,所以想看看人们是否尝试过任何想法。我最后的想法是简单地将它包装在 UIView 中并将它与 SwiftUI 一起使用,但我想避免这种情况并保持原生。
我在自定义 TabBar 中看到过一篇文章,但我想使用 Apple 提供的 TabBar 以避免将来出现任何差异。
谢谢!
编辑:使问题更清楚。
只需使用ZStack一个Button或任何您想要的视图即可...
struct MainTabView: View {
@State private var selection = 0
var body: some View {
ZStack(alignment: .bottom) {
TabView(selection: $selection) {
ContentView()
.tabItem {
Label("Tab 1", systemImage: "list.dash")
}
.tag(0)
ContentView()
.tabItem {
Label("Tab 2", systemImage: "list.dash")
}
.tag(1)
Spacer()
.tabItem {
EmptyView()
}
.tag(2)
ContentView()
.tabItem {
Label("Tab 3", systemImage: "square.and.pencil")
}
.tag(3)
ContentView()
.tabItem {
Label("Tab 4", systemImage: "square.and.pencil")
}
.tag(4)
}
Button {
} label: {
Image(systemName: "plus")
.tint(Color.white)
}
.frame(width: 50, height: 50)
.background(Color.green)
.clipShape(Circle())
}
.ignoresSafeArea(.keyboard) // usefull so the button doesn't move around on keyboard show
.onChange(of: selection) { [selection] newValue in
if newValue == 2 { // replace 2 with your index
self.selection = selection // reset the selection in case we somehow press the middle tab
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以引入新@State属性来存储所显示选项卡的旧标签。.onAppear { self.oldSelectedItem = self.selectedItem }并对除中间选项卡之外的每个选项卡执行下一个方法。中间的选项卡将负责显示操作表,其方法如下所示:
.onAppear {
self.shouldShowActionSheet.toggle()
self.selectedItem = self.oldSelectedItem
}
Run Code Online (Sandbox Code Playgroud)
工作示例:
import SwiftUI
struct ContentView: View {
@State private var selectedItem = 1
@State private var shouldShowActionSheet = false
@State private var oldSelectedItem = 1
var body: some View {
TabView (selection: $selectedItem) {
Text("Home")
.tabItem { Image(systemName: "house") }
.tag(1)
.onAppear { self.oldSelectedItem = self.selectedItem }
Text("Search")
.tabItem { Image(systemName: "magnifyingglass") }
.tag(2)
.onAppear { self.oldSelectedItem = self.selectedItem }
Text("Add")
.tabItem { Image(systemName: "plus.circle") }
.tag(3)
.onAppear {
self.shouldShowActionSheet.toggle()
self.selectedItem = self.oldSelectedItem
}
Text("Heart")
.tabItem { Image(systemName: "heart") }
.tag(4)
.onAppear { self.oldSelectedItem = self.selectedItem }
Text("Profile")
.tabItem { Image(systemName: "person.crop.circle") }
.tag(5)
.onAppear { self.oldSelectedItem = self.selectedItem }
}
.actionSheet(isPresented: $shouldShowActionSheet) { ActionSheet(title: Text("Title"), message: Text("Message"), buttons: [.default(Text("Option 1"), action: option1), .default(Text("Option 2"), action: option2) , .cancel()]) }
}
func option1() {
// do logic 1
}
func option2() {
// do logic 2
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Run Code Online (Sandbox Code Playgroud)
感谢Aleskey的精彩回答(标记为正确)。除了围绕 Modal 写的一篇中等文章之外,我还对它进行了一些改进。我发现它有点不同
这是 jist。
MainTabBarData 是一个 Observable 对象
final class MainTabBarData: ObservableObject {
/// This is the index of the item that fires a custom action
let customActiontemindex: Int
let objectWillChange = PassthroughSubject<MainTabBarData, Never>()
var previousItem: Int
var itemSelected: Int {
didSet {
if itemSelected == customActiontemindex {
previousItem = oldValue
itemSelected = oldValue
isCustomItemSelected = true
}
objectWillChange.send(self)
}
}
func reset() {
itemSelected = previousItem
objectWillChange.send(self)
}
/// This is true when the user has selected the Item with the custom action
var isCustomItemSelected: Bool = false
init(initialIndex: Int = 1, customItemIndex: Int) {
self.customActiontemindex = customItemIndex
self.itemSelected = initialIndex
self.previousItem = initialIndex
}
}
Run Code Online (Sandbox Code Playgroud)
这是 TabbedView
struct TabbedView: View {
@ObservedObject private var tabData = MainTabBarData(initialIndex: 1, customItemIndex: 2)
var body: some View {
TabView(selection: $tabData.itemSelected) {
Text("First Screen")
.tabItem {
VStack {
Image(systemName: "globe")
.font(.system(size: 22))
Text("Profile")
}
}.tag(1)
Text("Second Screen")
.tabItem {
VStack {
Image(systemName: "plus.circle")
.font(.system(size: 22))
Text("Profile")
}
}.tag(2)
Text("Third Screen")
.tabItem {
VStack {
Image(systemName: "number")
.font(.system(size: 22))
Text("Profile")
}
}.tag(3)
}.actionSheet(isPresented: $tabData.isCustomItemSelected) {
ActionSheet(title: Text("SwiftUI ActionSheet"), message: Text("Action Sheet Example"),
buttons: [
.default(Text("Option 1"), action: option1),
.default(Text("Option 2"), action: option2),
.cancel(cancel)
]
)
}
}
func option1() {
tabData.reset()
// ...
}
func option2() {
tabData.reset()
// ...
}
func cancel() {
tabData.reset()
}
}
struct TabbedView_Previews: PreviewProvider {
static var previews: some View {
TabbedView()
}
}
Run Code Online (Sandbox Code Playgroud)
类似的概念,只是利用了 SwiftUI 和 Combine 的强大功能。
| 归档时间: |
|
| 查看次数: |
2116 次 |
| 最近记录: |