SwiftUI中TabView的基本用法及外观样式设置

TabView提供了一个交互式界面,允许用户在其内部的子界面间自由的切换,TabView有两种显示模式,一个是DefaultTabViewStyle,另一个是PageTabViewStyle,本文将对DefaultTabViewStyle这种类型的基本使用和外观样式设置进行一下探索学习。

基本使用

DefaultTabViewStyle类型下的TabView就像我们在UIKit中用到的UITabViewController,可以作为构建App的一个基本根视图。
要创建带有Tab选项卡的用户界面,在TabView中添加视图,并对每个视图添加tabItem(_:)修饰符即可,比如下面这个简单的示例:

在这里插入图片描述
上面代码中,我们在TabView中添加了3个视图,并且给每个视图都添加了tabItem(_:)修饰符,该修饰符的闭包内支持传入一个Label组件或者Text组件加Image的组合方式。

不管是哪种方式都不支持外观的设置。如果用TextImage组合的方式,添加了除了这两个组件以外的组件,那也是没用的,系统只会认添加的第一个Text和第一个Image,其他的都忽略了。

另外可以添加.badge()修饰符,传入一个字符串,如下:

在这里插入图片描述
默认badge是红色背景白色文字。

在创建TabView的时候还支持传入一个selection值,用来记录当前选中的tab,当切换tab的时候,selection读取每个子界面的tag值。下面将代码加入tag,并将代码进行一下优化,首先定义一个TabType枚举,定义好要显示的界面,包括界面的文字和图标。

enum TabType: Int, Hashable {
  case home
  case videos
  case message

  var title: String {
    switch self {
      case .home:
        return "Home"
      case .videos:
        return "Videos"
      case .message:
        return "Message"
    }
  }

  var image: String {
    switch self {
      case .home:
        return "house.fill"
      case .videos:
        return "video.fill"
      case .message:
        return "message.fill"
    }
  }
}

有了这个后body的代码优化为:

  @State private var selectedTab: TabType = .home

  var body: some View {
    TabView(selection: $selectedTab) {

      HomeView(selectedTab: $selectedTab)
        .tabItem {
          Text(TabType.home.title)
          Image(systemName: TabType.home.image)
        }
        .tag(TabType.home)

      VideosView()
        .tabItem {
          Label(TabType.home.title, systemImage: TabType.home.image)
        }
        .tag(TabType.videos)

      MessageView()
        .tabItem {
          Text(TabType.home.title)
          Image(systemName: TabType.home.image)
        }
        .badge("8")
        .tag(TabType.message)
    }
  }

上面定义了TabType类型的selectedTab属性,默认值是.home,即默认显示Home界面。我们将selectedTab绑定到TabView中,并对每个子界面添加.tag()修饰符,传入对应的tag,这里的tag采用枚举自身的值。

界面切换只要改变selectedTab的值即可,在Home界面添加了一个Button,点击后跳转到Message界面,Home界面作为一个单独的界面,定义如下:

struct HomeView: View {
  @Binding var selectedTab: TabType

  var body: some View {
    ZStack {
      Color.cyan
        .ignoresSafeArea(edges: .top)
      
      Button(action: {
        selectedTab = TabType.message
      }, label: {
        Text("Go to Message page")
          .padding()
          .background(Color.red)
          .foregroundColor(.white)
          .clipShape(Capsule())
      })
    }
  }
}

Home界面定义了一个@Bingding修饰的selectedTab变量,用来绑定父界面的selectedTab变量,这样在Home界面改动selectedTab变量,父界面的selectedTab也会改变。
效果图如下:

在这里插入图片描述

样式设置

与之前的UIKit TabBar类似,选中的Tab默认为蓝色,而未选中的为灰色。另外,在UIKit中,整个标签栏默认有一个背景。

然而,如果想改变颜色来匹配我们自己App的主题,例如,选中是Tab的文字和图片是其他颜色,以及badge的背景色和颜色等等。

下面我们将使用的UIKit外观API,来设置TabView的外观样式,让我们看看下面的代码。

先说一下,给TabView组件添加.tint()修饰符,可以改变TabItem选中时的颜色,其他的就得靠UIKitAPI了。

设置选中的TabItem的颜色

.tint(Color.red) // 设置选中的tabitem的颜色。

设置未选中的TabItem的颜色

UITabBar.appearance().unselectedItemTintColor = .systemBrown

设置badge的背景色

UITabBarItem.appearance().badgeColor = .green

设置badge中文字的样式

UITabBarItem.appearance().setBadgeTextAttributes([.foregroundColor: UIColor.red, .font: UIFont.boldSystemFont(ofSize: 14)], for: .normal) // 未选中时
UITabBarItem.appearance().setBadgeTextAttributes([.foregroundColor: UIColor.blue], for: .selected) // 选中时

设置TabBar的背景色

UITabBar.appearance().backgroundColor = .yellow

设置TabItem中文字和图片的间距和偏移量

UITabBarItem.appearance().titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 5)

上面的这些设置,我们可以在初始化组件的时候设置,也可以在.onAppear中设置。

    .onAppear {
      UITabBar.appearance().unselectedItemTintColor = .systemBrown
      UITabBarItem.appearance().badgeColor = .green
      UITabBar.appearance().backgroundColor = .yellow
      UITabBarItem.appearance().titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 5)
      UITabBarItem.appearance().setBadgeTextAttributes([.foregroundColor: UIColor.red, .font: UIFont.boldSystemFont(ofSize: 14)], for: .normal)
      UITabBarItem.appearance().setBadgeTextAttributes([.foregroundColor: UIColor.blue], for: .selected)
    }

在这里插入图片描述

写在最后

以上就是TabView的基本用法及样式设置,希望对大家能有所帮助,下一篇文章继续看一下PageTabViewStyle样式下的TabView

最后,希望能够帮助到有需要的朋友,如果您觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

完整Demo代码如下:

import SwiftUI

enum TabType: Int, Hashable {
  case home
  case videos
  case message

  var title: String {
    switch self {
      case .home:
        return "Home"
      case .videos:
        return "Videos"
      case .message:
        return "Message"
    }
  }

  var image: String {
    switch self {
      case .home:
        return "house.fill"
      case .videos:
        return "video.fill"
      case .message:
        return "message.fill"
    }
  }
}

struct TabViewDemo: View {

  @State private var selectedTab: TabType = .home

  var body: some View {
    TabView(selection: $selectedTab) {

      HomeView(selectedTab: $selectedTab)
        .tabItem {
          Text(TabType.home.title)
          Image(systemName: TabType.home.image)
        }
        .tag(TabType.home)

      VideosView()
        .tabItem {
          Label(TabType.home.title, systemImage: TabType.home.image)
        }
        .tag(TabType.videos)

      MessageView()
        .tabItem {
          Text(TabType.home.title)
          Image(systemName: TabType.home.image)
        }
        .badge("8")
        .tag(TabType.message)
    }
    .tint(Color.red)
    .onAppear {
      UITabBar.appearance().unselectedItemTintColor = .systemBrown
      UITabBarItem.appearance().badgeColor = .green
      UITabBar.appearance().backgroundColor = .yellow
      UITabBarItem.appearance().titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 5)
      UITabBarItem.appearance().setBadgeTextAttributes([.foregroundColor: UIColor.red, .font: UIFont.boldSystemFont(ofSize: 14)], for: .normal)
      UITabBarItem.appearance().setBadgeTextAttributes([.foregroundColor: UIColor.blue], for: .selected)
    }
  }
}

#Preview {
    TabViewDemo()
}

struct HomeView: View {
  @Binding var selectedTab: TabType

  var body: some View {
    ZStack {
      Color.cyan
        .ignoresSafeArea(edges: .top)
      
      Button(action: {
        selectedTab = TabType.message
      }, label: {
        Text("Go to Message page")
          .padding()
          .background(Color.red)
          .foregroundColor(.white)
          .clipShape(Capsule())
      })
    }
  }
}

struct VideosView: View {
  var body: some View {
    ZStack {
      Color.blue
        .ignoresSafeArea(edges: .top)
    }
  }
}

struct MessageView: View {
  var body: some View {
    ZStack {
      Color.red
        .ignoresSafeArea(edges: .top)
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/648625.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android消息机制回顾(Handler、Looper、MessageQueue源码解析)

回顾: Android消息机制 Android消息机制主要指的是Handler的运行机制以及Handler所附带的MessageQueue和Looper的工作机制。 介绍 通过Handler 消息机制来解决线程之间通信问题,或者用来切换线程。特别是在更新UI界面时,确保了线程间的数…

Swift使用JSONDecoder处理json数据,实现json序列化和反序列化

Json数据处理是开发中不可获取的一项技能,如果你不会处理json数据,那你离失业就不远了,所以学完了swift基础教程,还是先老老实实学习一下json处理吧,有了这项技能,你才可以继续下一个网络请求阶段的开发&am…

C++第二十弹---深入理解STL中vector的使用

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 目录 1、vector的介绍 2、vector的使用 2.1、构造函数和赋值重载 2.1.1、构造函数的介绍 2.1.2、代码演示 2.2、容量操作 2.3、遍历 2.4、增删…

类和对象(上)【有关类的全面学习】【this指针的学习】

类和对象(上) 1.面向过程和面向对象初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C语言注重过程: C是基于面向对象的,关注的是对象&#xff0…

如何获取某个城市或区域的人口分布数据?

人口分布数据在多个领域都扮演着至关重要的角色。这些数据不仅反映了一个国家或地区的人口分布状况,而且为政策制定者、企业决策者和研究者提供了宝贵的信息。那么,我们如何获取这些重要的人口分布数据呢? 政府统计部门是最主要的来源。各国政…

绝缘鞋计量校准周期多长时间合适?校验检测方法是什么?

绝缘鞋的计量校准,通常是应用在电学相关领域,因此也是属于计量校准机构中的电学室管辖的范围,而绝缘鞋为了安全防护,也是采用了绝缘材料,其标准要求耐电压至少在15KV以下,可应用于工频(50到60F&…

git 检查用户是否是gitlab用户

背景: 公司代码要从老的git库迁到新的git库,老git库上部分提交用户在新git库上没有,解决方法: 让gitlab不再检查提交用户是否是gitlab用户。具体操作: 去掉下面的勾选,保存配置即可。

天气的雪碧图标(晴天,雨天,雪天,阴天,雾天,多云等)(2024-05-27)

天气的预览图标,可以自行下载,或者在资源中下载高清的

Matlab进阶绘图第57期—带填充纹理的横向柱状图

带填充纹理的横向柱状图是通过在原始横向柱状图的基础上添加不同的纹理得到的,可以很好地解决由于颜色区分不足而导致的对象识别困难问题。 由于Matlab中未提供纹理填充选项,因此需要大家自行设法解决。 本文使用Kesh Ikuma制作的hatchfill2工具&#…

buu[HCTF 2018]WarmUp(代码审计)

buu[HCTF 2018]WarmUp&#xff08;代码审计&#xff09; 题目 访问source.php <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["source">"source.php","hint">"hint.php…

屎山代码SSM转换Springboot

SSM项目转Springboot项目 最近很多人可能是在网上买的那种屎山代码&#xff0c;数据库都是拼音的那种 比如项目如下所示&#xff1a; 这种屎山代码我改过太多了&#xff0c;很多人可能无从下手&#xff0c;因为代码结构太混乱了&#xff0c;但是我改过太多这种代码&#xff0…

【SpeedAI科研小助手】2分钟解决知网维普AIGC检测

2分钟搞定AIGC率&#xff1f;还能降到0%&#xff1f; 使用方法&#xff1a; 打开SpeedAI科研小助手&#xff0c;将功能模式换成降AIGC率&#xff0c;后面可以一段一段自己改&#xff0c;也可以直接上传论文文件&#xff0c;SpeedAI直接帮你全文修改&#xff08;主打一个用户友…

【云原生】kubernetes中的认证、权限设置---RBAC授权原理分析与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

笔记本电脑的ip地址在哪里找

在数字化时代&#xff0c;IP地址作为网络设备的唯一标识&#xff0c;扮演着至关重要的角色。对于笔记本电脑用户而言&#xff0c;了解如何查找自己的IP地址不仅有助于网络故障排查&#xff0c;还能在网络安全和远程办公等场景中发挥关键作用。虎观代理小二将详细介绍笔记本电脑…

关于linux磁盘告警问题

案例&#xff1a;我们在执行df命令时&#xff0c;查看到磁盘利用率很高&#xff0c;但是到相对应的目录执行du -sh *来找大文件时进行删除时&#xff0c;发现各个目录相加并不大&#xff0c;如下图&#xff1a; 使用df命令查看到根(/)目录使用到33G&#xff0c;而du命令显示只使…

【一竞技DOTA2】北美SR战队官宣SabeRLighT-离队

1、近日北美SR战队官宣了旗下三号位选手SabeRLighT-正式离队&#xff0c;公告内容如下&#xff1a; “今日我们正式宣布&#xff0c;Jonas &#xff08;Saberlight&#xff09;Volek将离开队伍。这个决定由Jonas本人和其他团队成员共同做出。 在过去的几个月里&#xff0c;我们…

mysql中InnoDB的表空间--独立表空间

大家好&#xff0c;上篇文章我们在讲mysql数据目录的时候提到了表空间这个名词&#xff0c;它是一个抽象的概念&#xff0c;对于系统表空间来说&#xff0c;对应着文件系统中一个或多个实际文件&#xff1b;对于每个独立表空间来说&#xff0c;对应着文件系统中一个名为表名.ib…