SwiftfulUI icon indicating copy to clipboard operation
SwiftfulUI copied to clipboard

TabBarViewBuilder, shadow seems to not work

Open Alex-Vaiman opened this issue 1 year ago • 6 comments

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
    }
}

}

Alex-Vaiman avatar Mar 02 '24 03:03 Alex-Vaiman

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.

Alex-Vaiman avatar Mar 05 '24 10:03 Alex-Vaiman

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....

Alex-Vaiman avatar Mar 05 '24 21:03 Alex-Vaiman

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.

Alex-Vaiman avatar Mar 05 '24 23:03 Alex-Vaiman

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. :)

Alex-Vaiman avatar Mar 05 '24 23:03 Alex-Vaiman

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!

SwiftfulThinking avatar Mar 06 '24 00:03 SwiftfulThinking

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 onAppear and onDisappear, 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. _VariadicView can be emitted into your app just by using HStack since it is part of the @inlinable initializer.

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:

Alex-Vaiman avatar Mar 06 '24 01:03 Alex-Vaiman