Skip to content

Instantly share code, notes, and snippets.

@Inncoder
Created October 15, 2020 21:15
Show Gist options
  • Select an option

  • Save Inncoder/04cf4d5cf200a27039aa80fd3242008f to your computer and use it in GitHub Desktop.

Select an option

Save Inncoder/04cf4d5cf200a27039aa80fd3242008f to your computer and use it in GitHub Desktop.
Custom Tab Bar
//
// DarkTabBar.swift
// Animations
//
// Created by Inncoder on 10/10/2020.
// Copyright © 2020 Inncoder AS. All rights reserved.
//
import SwiftUI
struct DarkTabBar: View {
@ObservedObject var viewRouter: ViewRouter
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: tabCornerRadius)
.frame(width: tabSizeWidth, height: tabSizeHeight)
ZStack {
Rectangle()
.frame(width: 70, height: tabSizeHeight)
.background(gradientColor)
.opacity(0.5)
.mask(lightShape())
RoundedRectangle(cornerRadius: tabCornerRadius)
.frame(width: 45, height: 5)
.foregroundColor(.white)
.offset(x: 0, y: -tabSizeHeight / 2)
}
.offset(x: calcLightOffset(route: viewRouter.currentView), y: 0)
.animation(Animation.easeInOut)
HStack(spacing: (tabSizeWidth - (tabItemSize * CGFloat(Route.allCases.count))) / CGFloat(Route.allCases.count)) {
ForEach(0..<Route.allCases.count, id: \.self) { i in
Button(action: {
viewRouter.currentView = Route.allCases[i]
}, label: {
Image(systemName: viewRouter.imageName(route: Route.allCases[i]))
.resizable()
.frame(width: tabItemSize, height: tabItemSize)
.foregroundColor(Route.allCases[i] == viewRouter.currentView ? .white : Color(UIColor.darkGray))
.animation(Animation.easeInOut)
})
}
}
}
.mask(RoundedRectangle(cornerRadius: tabCornerRadius).frame(width: tabSizeWidth, height: tabSizeHeight))
}
//MARK: - Drawing constants
let gradientColor = LinearGradient(gradient: Gradient(colors: [.white, .clear]), startPoint: .top, endPoint: .bottom)
let tabCornerRadius: CGFloat = 15
let tabSizeWidth: CGFloat = 350
let tabSizeHeight: CGFloat = 65
let tabItemSize: CGFloat = 25
func calcLightOffset(route: Route) -> CGFloat {
let spacing = (tabSizeWidth - (tabItemSize * CGFloat(Route.allCases.count))) / CGFloat(Route.allCases.count)
let offset = spacing + tabItemSize
switch route {
case .home:
return -(offset * 2)
case .search:
return -offset
case .add:
return 0
case .likes:
return offset
case .account:
return offset * 2
}
}
}
struct lightShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let part = rect.maxX / 4
path.move(to: CGPoint(x: rect.minX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.maxX - part, y: rect.minY))
path.addLine(to: CGPoint(x: rect.minX + part, y: rect.minY))
path.closeSubpath()
return path
}
}
struct DarkTabBar_Previews: PreviewProvider {
static var previews: some View {
DarkTabBar(viewRouter: ViewRouter())
}
}
//
// MainView.swift
// Animations
//
// Created by Inncoder on 10/10/2020.
// Copyright © 2020 Inncoder AS. All rights reserved.
//
import SwiftUI
struct MainView: View {
@ObservedObject var viewRouter = ViewRouter()
var body: some View {
ZStack {
offWhite.edgesIgnoringSafeArea(.all)
switch viewRouter.currentView {
case .home:
TestView(text: "Home")
case .search:
TestView(text: "Search")
case .add:
TestView(text: "Add")
case .likes:
TestView(text: "Likes")
case .account:
TestView(text: "Account")
}
VStack {
Spacer()
DarkTabBar(viewRouter: viewRouter)
}
}
}
//MARK: - Drawing constants
let offWhite = Color(red: 225 / 255, green: 225 / 255, blue: 235 / 255)
}
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}
//
// ViewRouter.swift
// Animations
//
// Created by Inncoder on 10/10/2020.
// Copyright © 2020 Inncoder AS. All rights reserved.
//
import SwiftUI
class ViewRouter: ObservableObject {
@Published var currentView: Route = Route.home
func imageName(route: Route) -> String {
switch route {
case .home:
return "house.fill"
case .search:
return "magnifyingglass"
case .add:
return "plus.app"
case .likes:
return "heart"
case .account:
return "person.fill"
}
}
}
enum Route: CaseIterable {
case home
case search
case add
case likes
case account
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment