Button SwiftUI TabView:从不同视图设置所选tabItem,但检测重复选择
我想显示一个Button SwiftUI TabView:从不同视图设置所选tabItem,但检测重复选择,button,swiftui,controls,tabview,Button,Swiftui,Controls,Tabview,我想显示一个选项卡来显示不同的屏幕。我的第一个屏幕(主页)显示三个按钮,可以从三个屏幕中选择一个显示。 但是(!)我必须检查是否重复选择了一个选项卡,以触发本例中的特殊操作 screen2重复选择的检测工作正常,但是我无法通过按钮设置选择。 我尝试使用@EnvironmentalObject,但在我的TabView.selection中未观察到此对象的更改 import SwiftUI @main struct TestApp: App { static let
选项卡来显示不同的屏幕。我的第一个屏幕(主页)显示三个按钮,可以从三个屏幕中选择一个显示。
但是(!)我必须检查是否重复选择了一个选项卡,以触发本例中的特殊操作
screen2重复选择的检测工作正常,但是我无法通过按钮设置选择。
我尝试使用@EnvironmentalObject
,但在我的TabView.selection中未观察到此对象的更改
import SwiftUI
@main
struct TestApp: App {
static let kIndex0 = 0
static let kIndex1 = 1
static let kIndex2 = 2
var appState = AppState()
@State private var selection = TestApp.kIndex0
var body: some Scene {
// this code is required to detect a repeated selection of
// the same tab to trigger a special action
let index = Binding<Int>(
get: { self.selection },
set: {
if $0 == TestApp.kIndex1 && self.selection == $0 {
print("Trigger special action for index 1")
}
print("Pressed tab: \($0) self.selction: \(self.selection) app.selectedTab: \(appState.selectedTab)")
self.selection = $0
appState.selectedTab = $0
})
WindowGroup {
TabView(selection: index) {
First()
.environmentObject(appState)
.tabItem {
Image(systemName: "1.circle")
Text("Home")
}.tag(TestApp.kIndex0)
Text("Second Content View")
.tabItem {
Image(systemName: "2.circle")
Text("Screen Two")
}.tag(TestApp.kIndex1)
Text("Third Content View")
.tabItem {
Image(systemName: "3.circle")
Text("Screen Three")
}.tag(TestApp.kIndex2)
}
}
}
}
class AppState: ObservableObject {
@Published var selectedTab = TestApp.kIndex0
}
/*
Place to buttons which should select on of the the two
tabs of TestUI
*/
struct First: View {
@EnvironmentObject var appState: AppState
var body: some View {
VStack(alignment: .leading, spacing: 20) {
AButton(tabIndex: TestApp.kIndex0, iconName: "1.circle", text: "This first screen")
.environmentObject(appState)
AButton(tabIndex: TestApp.kIndex1, iconName: "2.circle", text: "Second screen")
.environmentObject(appState)
AButton(tabIndex: TestApp.kIndex1, iconName: "3.circle", text: "Third screen")
.environmentObject(appState)
}
}
}
struct AButton: View {
let tabIndex: Int
let iconName: String
let text: String
@EnvironmentObject var appState: AppState
var body: some View {
Button(action: {
appState.selectedTab = tabIndex
}) {
HStack() {
Image(systemName: iconName)
.imageScale(.large)
.frame(minWidth: 50)
Text(text)
}
}
}
}
导入快捷界面
@主要
struct TestApp:App{
静态let kIndex0=0
静态let kIndex1=1
静态let kIndex2=2
var appState=appState()
@国家私有风险值选择=TestApp.kIndex0
var body:一些场景{
//需要此代码来检测重复选择的
//使用相同的选项卡触发特殊操作
让索引=绑定(
获取:{self.selection},
设置:{
如果$0==TestApp.kIndex1&&self.selection==0{
打印(“触发索引1的特殊操作”)
}
打印(“按下的选项卡:\($0)self.selection:\(self.selection)app.selectedTab:\(appState.selectedTab)”)
self.selection=$0
appState.selectedTab=$0
})
窗口组{
选项卡视图(选择:索引){
第一()
.environmentObject(appState)
.tabItem{
图像(系统名称:“1.圆圈”)
文本(“主页”)
}.tag(TestApp.kIndex0)
文本(“第二内容视图”)
.tabItem{
图像(系统名称:“2.圆圈”)
文本(“屏幕二”)
}.tag(TestApp.kIndex1)
文本(“第三内容视图”)
.tabItem{
图像(系统名称:“3.圆圈”)
文本(“屏幕三”)
}.tag(TestApp.kIndex2)
}
}
}
}
类AppState:ObservableObject{
@已发布变量selectedTab=TestApp.kIndex0
}
/*
放置到按钮,该按钮应在两个按钮中选择一个
TestUI的选项卡
*/
结构优先:视图{
@EnvironmentObject变量appState:appState
var body:一些观点{
VStack(对齐:。前导,间距:20){
AButton(tabIndex:TestApp.kIndex0,图标名:“1.圆圈”,文本:“第一个屏幕”)
.environmentObject(appState)
AButton(tabIndex:TestApp.kIndex1,图标名:“2.圆圈”,文本:“第二屏”)
.environmentObject(appState)
AButton(tabIndex:TestApp.kIndex1,图标名:“3.圆圈”,文本:“第三屏”)
.environmentObject(appState)
}
}
}
结构AButton:视图{
让tabIndex:Int
让我来命名:字符串
让文本:字符串
@EnvironmentObject变量appState:appState
var body:一些观点{
按钮(操作:{
appState.selectedTab=tabIndex
}) {
HStack(){
图像(系统名称:iconName)
.imageScale(.large)
.框架(最小宽度:50)
文本(文本)
}
}
}
}
您需要观察appState
,您根本不需要选择(它只是一个副本)
我已将所有内容放入单独的ContentView
(只为场景保留场景)
使用Xcode 12/iOS 14进行测试
struct ContentView: View {
@StateObject var appState = AppState()
var body: some View {
// this code is required to detect a repeated selection of
// the same tab to trigger a special action
let index = Binding<Int>(
get: { self.appState.selectedTab },
set: {
if $0 == TestApp.kIndex1 && self.appState.selectedTab == $0 {
print("Trigger special action for index 1")
}
print("Pressed tab: \($0) app.selectedTab: \(appState.selectedTab)")
appState.selectedTab = $0
})
TabView(selection: index) {
First()
.environmentObject(appState)
.tabItem {
Image(systemName: "1.circle")
Text("Home")
}.tag(TestApp.kIndex0)
Text("Second Content View")
.tabItem {
Image(systemName: "2.circle")
Text("Screen Two")
}.tag(TestApp.kIndex1)
Text("Third Content View")
.tabItem {
Image(systemName: "3.circle")
Text("Screen Three")
}.tag(TestApp.kIndex2)
}
}
}
class AppState: ObservableObject {
@Published var selectedTab = TestApp.kIndex0
}
struct First: View {
@EnvironmentObject var appState: AppState
var body: some View {
VStack(alignment: .leading, spacing: 20) {
AButton(tabIndex: TestApp.kIndex0, iconName: "1.circle", text: "This first screen")
AButton(tabIndex: TestApp.kIndex1, iconName: "2.circle", text: "Second screen")
AButton(tabIndex: TestApp.kIndex2, iconName: "3.circle", text: "Third screen")
}
}
}
struct AButton: View {
let tabIndex: Int
let iconName: String
let text: String
@EnvironmentObject var appState: AppState
var body: some View {
Button(action: {
appState.selectedTab = tabIndex
}) {
HStack() {
Image(systemName: iconName)
.imageScale(.large)
.frame(minWidth: 50)
Text(text)
}
}
}
}
struct ContentView:View{
@StateObject变量appState=appState()
var body:一些观点{
//需要此代码来检测重复选择的
//使用相同的选项卡触发特殊操作
让索引=绑定(
获取:{self.appState.selectedTab},
设置:{
如果$0==TestApp.kIndex1&&self.appState.selectedTab==0{
打印(“触发索引1的特殊操作”)
}
打印(“按下的选项卡:\($0)app.selectedTab:\(appState.selectedTab)”)
appState.selectedTab=$0
})
选项卡视图(选择:索引){
第一()
.environmentObject(appState)
.tabItem{
图像(系统名称:“1.圆圈”)
文本(“主页”)
}.tag(TestApp.kIndex0)
文本(“第二内容视图”)
.tabItem{
图像(系统名称:“2.圆圈”)
文本(“屏幕二”)
}.tag(TestApp.kIndex1)
文本(“第三内容视图”)
.tabItem{
图像(系统名称:“3.圆圈”)
文本(“屏幕三”)
}.tag(TestApp.kIndex2)
}
}
}
类AppState:ObservableObject{
@已发布变量selectedTab=TestApp.kIndex0
}
结构优先:视图{
@EnvironmentObject变量appState:appState
var body:一些观点{
VStack(对齐:。前导,间距:20){
AButton(tabIndex:TestApp.kIndex0,图标名:“1.圆圈”,文本:“第一个屏幕”)
AButton(tabIndex:TestApp.kIndex1,图标名:“2.圆圈”,文本:“第二屏”)
AButton(tabIndex:TestApp.kIndex2,图标名:“3.圆圈”,文本:“第三屏”)
}
}
}
结构AButton:视图{
让tabIndex:Int
让我来命名:字符串
让文本:字符串
@EnvironmentObject变量appState:appState
var body:一些观点{
按钮(操作:{
appState.selectedTab=tabIndex
}) {
HStack(){