SwiftfulUI
SwiftfulUI copied to clipboard
TabBarViewBuilder, shadow seems to not work
I think u cannot apply shadow directly on color... but applying, on shape works.
public var body: some View {
HStack(spacing: 0) {
ForEach(tabs, id: \.self) { tab in
tabView(tab)
.background(Color.black.opacity(0.001))
.onTapGesture {
switchToTab(tab: tab)
}
}
}
.padding(.horizontal, insetPadding)
.background(
ZStack {
if let backgroundColor = backgroundColor {
backgroundColor
.cornerRadius(cornerRadius)
.shadow(
color: shadow.color, radius: shadow.radius, x: shadow.x, y: shadow.y
)
} else {
Color.clear
}
}
)
.padding(outerPadding)
}
and i think this extension is redundant? (i am not sure about old version of swift-UI, but in my setup, it just ignores negative values.
extension View {
@ViewBuilder func cornerRadiusIfNeeded(cornerRadius: CGFloat) -> some View {
if cornerRadius > 0 {
self
.cornerRadius(cornerRadius)
} else {
self
}
}
}
also... the bar gets on top of keyboard ))), this an easy fix. and the tabs dont call on appear, on disappear. this is probably something that ca not be solved.. i have seen lib that solve it, but in the cost of using private apis.. VariadicView.
what even worse...
public struct ChockBarItem: Hashable { public let title: String? public let iconName: String? public let image: UIImage? public private(set) var badgeCount: Int?
public init(title: String?, iconName: String? = nil, image: UIImage? = nil, badgeCount: Int? = nil) {
self.title = title
self.iconName = iconName
self.image = image
self.badgeCount = badgeCount
}
public mutating func updateBadgeCount(to count: Int) {
badgeCount = count
}
}
the default hash func takes budge count into account, but badgeCount is not a @State....
public struct BarItem: Hashable {
private(set) var title: String?
private(set) var iconName: String?
private(set) var image: UIImage?
private(set) var badgeCount: Int?
public init(title: String?, iconName: String? = nil, image: UIImage? = nil, badgeCount: Int? = nil) {
self.title = title
self.iconName = iconName
self.image = image
self.badgeCount = badgeCount
}
public mutating func updateBadgeCount(to count: Int) {
badgeCount = count
}
// is equal for selected tab, must ignore badgeCount!
internal func isSame(other: BarItem) -> Bool {
return title == other.title
&& iconName == other.iconName
&& image == other.image
}
}
you can add this function, and use this when you compare selection, careful, you have to use this function in two places, 1
func body(content: Content) -> some View {
ZStack {
if didLoad || selection == tab {
content
.opacity(selection == tab ? 1 : 0)
.onAppear {
didLoad = true
}
}
}
}
2
.foregroundColor(selection == tab ? accentColor : defaultColor) when you set the tab color.
I've gained valuable insights from your expertise. While I may not be a novice developer, I'm relatively new to SwiftUI. I wanted to share my iteration of your tab manager, which I've been working on: VardiacTab.
Additionally, I found these resources helpful in comprehending the intricacies of SwiftUI:
https://www.emergetools.com/blog/posts/how-to-use-variadic-view https://medium.com/@Barbapapapps/beyond-basics-implementing-a-custom-picker-in-swiftui-88c01e283ac1
By the way, this could potentially be a valuable addition to your new paid advanced course. :)
Hey @Aelx-Vaiman Thanks for the updates here. I actually do not use this component any more and I only use native tabbars because they are more performant. You are more than welcome to open a PR with updates for this component if you'd like. Otherwise I'll check out your VariadicTab once it's complete!
I've completed the project, and while there's room for further refinement, such as adding the option to place the tabBar on different edges of the screen, the core functionality is now in place. The API closely resembles what you had before, but with some simplifications. Notably, the addBarItem function now only requires the tab itself as a parameter, eliminating the need to pass the selection.
Regarding performance, I believe it's on par with native solutions, with no notable reasons why it wouldn't be.
Here's a summary of the improvements:
- A bug has been fixed.
- SwiftUI View Lifecycle updates, like
onAppearandonDisappear, are now properly honored.
However, it's important to acknowledge that there is a drawback associated with the use of a private API. While many apps utilize this API without issues, it's not officially supported by Apple. Nonetheless, it's worth noting that this particular API is inlined and frozen, meaning it's highly unlikely to ever change. Any alteration to this API would risk breaking functionality across all SwiftUI apps currently available on the App Store.
The use of this API is why I haven't submitted a pull request. If you're comfortable with this level of risk, please feel free to review the code and integrate it into your project.
This information is sourced from the links I provided earlier.
This is a private API, so is it safe to use in production? I believe it is, and it has been successfully used by many apps.
The key reason you can use it is that the VariadicView API is already used in apps, even without developers writing the code explicitly.
_VariadicViewcan be emitted into your app just by usingHStacksince it is part of the@inlinableinitializer.
this is a private API, so is it safe to use in production? I think it is, and it has been used successfully by many apps.
The key reason you can use it is the VariadicView API is already used in apps, even without developers writing the code explicitly. _VariadicView can be emitted into your app just by using HStack since it is part of the @inlinable initializer: