Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 🐛 tab bar styles #761

Merged
merged 1 commit into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "placeholderImageLight.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,35 @@ struct TabBarModel: Identifiable {
}

struct TabViewDetailView: View {
@Binding var numberOfTabs: Int
@Binding var isCustomColor: Bool
@Binding var isCustomSelectionIndicatorImage: Bool
@Binding var isCustomBackgroundImage: Bool
var numberOfTabs: Int
var isCustomColor: Bool
var isCustomSelectionIndicatorImage: Bool
var isCustomBackgroundImage: Bool
var isSystemTabView: Bool
@State private var selection = 0
@State private var accendColor = Color.random
@State private var selectionAudioPlayer: AVAudioPlayer!
@State private var accentColor = Color.preferredColor(.tintColor)
@State private var selectionAudioPlayer: AVAudioPlayer?

var tabs: [TabBarModel] = [TabBarModel(name: "bicycle", badge: "2", imageName: "bicycle"),
TabBarModel(name: "list", imageName: "list.dash"),
TabBarModel(name: "cart", badge: "NEW", imageName: "cart"),
TabBarModel(name: "person", imageName: "person.crop.circle"),
TabBarModel(name: "1", imageName: "1.square"),
init(numberOfTabs: Int,
isCustomColor: Bool,
isCustomSelectionIndicatorImage: Bool,
isCustomBackgroundImage: Bool,
isSystemTabView: Bool)
{
self.numberOfTabs = numberOfTabs
self.isCustomColor = isCustomColor
self.isCustomSelectionIndicatorImage = isCustomSelectionIndicatorImage
self.isCustomBackgroundImage = isCustomBackgroundImage
self.isSystemTabView = isSystemTabView

self.configTabStyles()
}

var tabs: [TabBarModel] = [TabBarModel(name: "Overview", badge: "2", imageName: "house.fill"),
TabBarModel(name: "Cart", imageName: "cart"),
TabBarModel(name: "Saved", badge: "NEW", imageName: "bookmark"),
TabBarModel(name: "Profile", imageName: "person.crop.circle"),
TabBarModel(name: "To-Dos", imageName: "tray.and.arrow.down"),
TabBarModel(name: "2", imageName: "2.circle"),
TabBarModel(name: "3", imageName: "3.circle.fill")]

Expand All @@ -31,17 +47,16 @@ struct TabViewDetailView: View {
set: {
if self.selection != $0 {
self.selection = $0
self.accendColor = Color.random
self.accentColor = self.isCustomColor ? Color.random : Color.preferredColor(.tintColor)
}

self.selectionAudioPlayer?.play()
self.playTabSound()
}
) }

var body: some View {
TabView(selection: self.handler) {
ForEach(0 ..< self.numberOfTabs, id: \.self) { index in
let t = self.tabs[index]
let model = self.tabs[index]
Group {
if index.isMultiple(of: 2) {
Color.random
Expand All @@ -51,82 +66,103 @@ struct TabViewDetailView: View {
}
}
}
.badge(t.badge)
.badge(model.badge)
.tag(index)
.tabItem {
Label(
title: { Text(t.name) },
icon: { Image(systemName: t.imageName) }
)
Label(model.name, systemImage: model.imageName)
}
}
}
.navigationTitle("Customized TabView")
.accentColor(self.accendColor)
.onAppear {
if let path = Bundle.main.path(forResource: "08 Tap", ofType: "wav") {
let url = URL(fileURLWithPath: path)
do {
self.selectionAudioPlayer = try AVAudioPlayer(contentsOf: url)
self.selectionAudioPlayer.prepareToPlay()
} catch let error as NSError {
print("Error creating AVAudioPlayer \(error)")
}
}

if self.isCustomColor {
self.customTabColor()
} else {
self.resetTabColor()
}
.navigationTitle("TabView Example")
.onDisappear {
self.resetToSystemDefault()
}
}

func configTabStyles() {
if !self.isSystemTabView {
if self.isCustomSelectionIndicatorImage {
UITabBar.appearance().selectionIndicatorImage = UIImage(systemName: "car")
UITabBar.appearance().selectionIndicatorImage = UIImage(systemName: "circle.fill")?.withConfiguration(UIImage.SymbolConfiguration(scale: .small))
} else {
UITabBar.appearance().selectionIndicatorImage = nil
}

if self.isCustomBackgroundImage {
UITabBar.appearance().backgroundImage = UIImage(named: "SAPLogo")?.stretchableImage(withLeftCapWidth: 0, topCapHeight: 0)
if self.isCustomColor {
self.customTabStyle()
} else {
UITabBar.appearance().backgroundImage = nil
self.fioriTabStyle()
}
}
.onDisappear {
self.resetTabColor()
UITabBar.appearance().selectionIndicatorImage = nil
UITabBar.appearance().backgroundImage = nil
}

func customTabStyle() {
let normalAttributes = [NSAttributedString.Key.font: UIFont.preferredFioriFont(forTextStyle: .footnote, weight: .regular),
NSAttributedString.Key.foregroundColor: UIColor(Color.random)]
let selectedAttributes = [NSAttributedString.Key.font: UIFont.preferredFioriFont(forTextStyle: .footnote, weight: .bold),
NSAttributedString.Key.foregroundColor: UIColor(Color.random)]
let appearance = UITabBarAppearance()
appearance.stackedLayoutAppearance.normal.titleTextAttributes = normalAttributes
appearance.stackedLayoutAppearance.selected.titleTextAttributes = selectedAttributes
appearance.stackedLayoutAppearance.normal.iconColor = UIColor(Color.random)
appearance.stackedLayoutAppearance.normal.badgeBackgroundColor = UIColor(Color.random)
appearance.stackedLayoutAppearance.normal.badgeTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(Color.random)]
appearance.stackedLayoutAppearance.selected.badgeTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(Color.random)]
if self.isCustomBackgroundImage {
appearance.backgroundImage = UIImage(named: "placeholderImageLight")?.stretchableImage(withLeftCapWidth: 0, topCapHeight: 0)
} else {
appearance.backgroundImage = nil
}
UITabBar.appearance().standardAppearance = appearance
UITabBar.appearance().scrollEdgeAppearance = appearance
UITabBar.appearance().unselectedItemTintColor = UIColor(Color.preferredColor(.primaryLabel))
}

func customTabColor() {
UITabBarItem.appearance().setTitleTextAttributes([.font: UIFont.preferredFioriFont(forTextStyle: .title3),
.foregroundColor: UIColor(Color.preferredColor(.primaryLabel))], for: .normal)
UITabBarItem.appearance().setTitleTextAttributes([.font: UIFont.preferredFioriFont(forTextStyle: .title3),
.foregroundColor: UIColor(Color.random)], for: .selected)
UITabBarItem.appearance().setBadgeTextAttributes([.font: UIFont.preferredFioriFont(forTextStyle: .callout),
.foregroundColor: UIColor(Color.random)], for: .normal)
UITabBarItem.appearance().setBadgeTextAttributes([.font: UIFont.preferredFioriFont(forTextStyle: .callout),
.foregroundColor: UIColor(Color.random)], for: .selected)
UITabBar.appearance().unselectedItemTintColor = UIColor(Color.preferredColor(.red11))
UITabBar.appearance().backgroundColor = UIColor(Color.preferredColor(.green11))
UITabBarItem.appearance().badgeColor = UIColor(Color.preferredColor(.base1))
func fioriTabStyle() {
let normalAttributes = [NSAttributedString.Key.font: UIFont.preferredFioriFont(forTextStyle: .caption2, weight: .regular),
NSAttributedString.Key.foregroundColor: UIColor(Color.preferredColor(.primaryLabel))]
let selectedAttributes = [NSAttributedString.Key.font: UIFont.preferredFioriFont(forTextStyle: .caption2, weight: .bold),
NSAttributedString.Key.foregroundColor: UIColor(Color.preferredColor(.tintColor))]
let appearance = UITabBarAppearance()
appearance.stackedLayoutAppearance.normal.titleTextAttributes = normalAttributes
appearance.stackedLayoutAppearance.selected.titleTextAttributes = selectedAttributes
appearance.stackedLayoutAppearance.normal.iconColor = UIColor(Color.preferredColor(.primaryLabel))
appearance.stackedLayoutAppearance.selected.iconColor = UIColor(Color.preferredColor(.tintColor))
if self.isCustomBackgroundImage {
appearance.backgroundImage = UIImage(named: "placeholderImageLight")?.stretchableImage(withLeftCapWidth: 0, topCapHeight: 0)
} else {
appearance.backgroundImage = nil
}
UITabBar.appearance().standardAppearance = appearance
UITabBar.appearance().scrollEdgeAppearance = appearance
UITabBar.appearance().unselectedItemTintColor = UIColor(Color.preferredColor(.primaryLabel))
}

func resetTabColor() {
func resetToSystemDefault() {
UITabBar.appearance().unselectedItemTintColor = nil
UITabBar.appearance().backgroundColor = nil
UITabBarItem.appearance().badgeColor = UIColor.systemRed

UITabBarItem.appearance().setTitleTextAttributes([:], for: .normal)
UITabBarItem.appearance().setTitleTextAttributes([:], for: .selected)
UITabBarItem.appearance().setBadgeTextAttributes([:], for: .normal)
UITabBarItem.appearance().setBadgeTextAttributes([:], for: .selected)
UITabBarItem.appearance().badgeColor = nil
}

func playTabSound() {
if let url = Bundle.main.url(forResource: "08 Tap", withExtension: "wav") {
do {
self.selectionAudioPlayer = try AVAudioPlayer(contentsOf: url)
self.selectionAudioPlayer?.prepareToPlay()
self.selectionAudioPlayer?.play()
} catch let error as NSError {
print("Error creating AVAudioPlayer \(error)")
}
}
}
}

#Preview {
TabViewDetailView(numberOfTabs: .constant(6),
isCustomColor: .constant(false),
isCustomSelectionIndicatorImage: .constant(false),
isCustomBackgroundImage: .constant(true))
TabViewDetailView(numberOfTabs: 6,
isCustomColor: false,
isCustomSelectionIndicatorImage: false,
isCustomBackgroundImage: true,
isSystemTabView: false)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,35 @@ struct TabViewExample: View {
@State var isCustomColor: Bool = false
@State var isCustomSelectionIndicatorImage: Bool = false
@State var isCustomBackgroundImage: Bool = false
@State var isSystemTabView: Bool = false

var body: some View {
Form {
if self.isModalPresentation {
HStack {
Text("Selecte to Test")
Text("Select to Test")
Spacer()
}
.contentShape(Rectangle())
.onTapGesture {
self.isPresented.toggle()
}
.sheet(isPresented: self.$isPresented) {
TabViewDetailView(numberOfTabs: self.$numberOfTabs,
isCustomColor: self.$isCustomColor,
isCustomSelectionIndicatorImage: self.$isCustomSelectionIndicatorImage,
isCustomBackgroundImage: self.$isCustomBackgroundImage)
TabViewDetailView(numberOfTabs: self.numberOfTabs,
isCustomColor: self.isCustomColor,
isCustomSelectionIndicatorImage: self.isCustomSelectionIndicatorImage,
isCustomBackgroundImage: self.isCustomBackgroundImage,
isSystemTabView: self.isSystemTabView)
}
} else {
NavigationLink {
TabViewDetailView(numberOfTabs: self.$numberOfTabs,
isCustomColor: self.$isCustomColor,
isCustomSelectionIndicatorImage: self.$isCustomSelectionIndicatorImage,
isCustomBackgroundImage: self.$isCustomBackgroundImage)
TabViewDetailView(numberOfTabs: self.numberOfTabs,
isCustomColor: self.isCustomColor,
isCustomSelectionIndicatorImage: self.isCustomSelectionIndicatorImage,
isCustomBackgroundImage: self.isCustomBackgroundImage,
isSystemTabView: self.isSystemTabView)
} label: {
Text("Selecte to Test")
Text("Select to Test")
}
}

Expand All @@ -46,11 +49,12 @@ struct TabViewExample: View {
}

Toggle("Modal Presentation", isOn: self.$isModalPresentation)
Toggle("Custom Colors", isOn: self.$isCustomColor)
Toggle("Custom Colors and Font Size", isOn: self.$isCustomColor)
Toggle("Custom Selection Indicator Image", isOn: self.$isCustomSelectionIndicatorImage)
Toggle("Custom Background Image", isOn: self.$isCustomBackgroundImage)
Toggle("SwiftUI TabView", isOn: self.$isSystemTabView)
}
.navigationTitle("TabView Example")
.navigationTitle("TabView Options")
}
}

Expand Down
Loading