swift - SwiftUI 中的 Tabbar 中间按钮实用功能
问题描述
我正在尝试复制一个“Instagram” tabBar
,其中中间有一个“实用程序”按钮,不一定属于tabBar
生态系统。
我附上了这个 gif 来展示我所追求的行为。来描述问题。中间的标签栏(黑色加号)是单击一个 ActionSheet 而不是切换视图。
我如何在 UIKit 中做到这一点只是使用
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
print("Selected item")
}
函数来自UITabBarDelegate
. 但显然我们不能在 SwiftUI 中做到这一点,所以我们想看看人们是否尝试过任何想法。我最后的想法是将它简单地包装在 UIView 中并将其与 SwiftUI 一起使用,但希望避免这种情况并保持原生状态。
我在自定义 TabBar 中看到了一篇文章,但想使用 Apple 提供的 TabBar 以避免将来出现任何差异。
谢谢!
编辑:使问题更清楚。
解决方案
感谢Aleskey的出色回答(标记为正确)。除了围绕 Modal 编写的中篇文章之外,我对它进行了一些改进。我发现它有点不同
这是吉斯特。
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
}
}
这是 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()
}
}
类似的概念,只是使用了 SwiftUI 和 Combine 的强大功能。
推荐阅读
- wpf - 为什么我无法在 Wpf 的应用程序内使用 WebView 导航 html 文件?
- javascript - 使用 moment.js 更改日期时间戳上的时区,而不更改时间
- jquery - 添加两个 JSON 对象并创建一个新对象
- java - ClassNotFoundException:edu.stanford.nlp.tagger.maxent.ExtractorNonAlphanumeric
- java - 如何检查数组是否与参数具有相同的值?
- asynchronous - Dart中以同步方式调用异步函数
- c++ - 变量定义到 C++ 中的布尔值转换
- php - PDO 作为构造函数参数
- javascript - dp-date-picker 中的无效 Jalali 年份 -100721
- flutter - 无法在颤振中访问提供者