Closed takehilo closed 6 years ago
Hey! I don't know why you want to change tabbar line width, but that does not work because the line width changed via animation: https://github.com/CosmicMind/Material/blob/6b989a48aeb1317411396b8ea970a15a45e29e9b/Sources/iOS/TabBar.swift#L602-L603
When you tap a tabItem or swipe the controller, above code is called. Motion
works with CoreAnimation
which animates view from old values to the new values on presentationLayer
and sets the new values back to the actual layer/view when animation is done. So changing tabBar.line.width
won't work because what's actually shown on the screen during animation is presentationlayer
and after animation is done values of presentationLayer will be passed to the actual layer/view.
Actually there is hackish way to achieve what you want. Since the frame of the line is calculated from tabItem
itself, we can tweak tabItem
properties before animation is fired and set it back before layout cycle happens:
class MyTabsController: TabsController, TabBarDelegate {
override func prepare() {
super.prepare()
tabBar.delegate = self
}
func tabBar(tabBar: TabBar, willSelect tabItem: TabItem) {
let desiredWidth: CGFloat = 100
let w = tabItem.frame.width
let x = tabItem.center.x
tabItem.frame.size.width = desiredWidth
tabItem.frame.origin.x = x - desiredWidth / 2
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
tabItem.frame.size.width = w
tabItem.frame.origin.x = x - w / 2
}
}
@danieldahan What do yo think maybe we should add something like:
func tabBar(tabBar: TabBar, lineWidthFor tabItem: TabItem) -> CGFloat
I think for the purposes of customization, we can offer an enum that is by default set to auto
for line transition changes, and then add a custom enum that accepts a value for the desired width. @OrkhanAlikhanov what do you think?
Well, that sounds reasonable. Can tabItems have different widths? If so, then lines can also have different widths based on tabItem's width. So, we need another case accepting closure for dynamic calculation.
enum TabBarLineWidthStyle {
case auto
case fixed(CGFloat)
case custom((TabBarItem) -> CGFloat)
}
Usage:
tabBar.tabBarLineWidthStyle = .auto
tabBar.tabBarLineWidthStyle = .fixed(100)
tabBar.tabBarLineWidthStyle = .custom { tabItem in
return tabItem.bounds.width - 20
}
What do you think?
I think the 3 options would solve all cases nicely. Maybe we can rename the enum to TabBarItemsStyle
. Not so sure I like the word Width
in there. In either case, the naming could be changed on final review when we PR the branch into dev.
Please find the solution for this in Material 2.16.2. Thank you!
I want to change the width of TabBar line. I tried the following in the subclass of TabsController but it didn't work. How can I do this?