CosmicMind / Material

A UI/UX framework for creating beautiful applications.
http://cosmicmind.com
MIT License
12k stars 1.26k forks source link

Cannot customize appearance of PageTabBarController tab bar #710

Closed markst closed 7 years ago

markst commented 7 years ago

I'm using a PageTabBarController & wish to make the tab button text colour different upon selecting a tab.

However I'm unable to customize the appearance of the tab bar since the pageTabBar property is defined as a constant & cannot be overridden with a stored property.

daniel-jonathan commented 7 years ago

Hey,

If you want to update the PageTabBar, you would need to edit the buttons directly. There is a feature request to add functionality to make this easier, https://github.com/CosmicMind/Material/issues/683.

You can access the buttons through the pageTabBar.buttons property. If you need to do this from one of the view controllers, you can use the pageTabBarController optional view controller property.

pageTabBarController?.pageTabBar.buttons.first?.image = ...

Are you looking to set the pageTabBarController.pageTabBar property to a subclass of the PageTabBar ?

daniel-jonathan commented 7 years ago

You could use an extension as well, PageTabBar is an open class.

open class PageTabBar: TabBar
daniel-jonathan commented 7 years ago

Hey I haven't heard back from you. If you still have an issue, please reopen this. Thank you!

markst commented 7 years ago

image

daniel-jonathan commented 7 years ago

@markst try subclassing CSTabBar: PageTabBar not TabBar.

markst commented 7 years ago

Ah whoops. Still seems to be an issue: image

daniel-jonathan commented 7 years ago

This might be because it is a let property. Another option is to add an extension to the PageTabBar with your changes. I would need to double check my statement: This might be because it is a let property, but you may be able to do that while you work with your code.

stachon commented 7 years ago

I have the same issue. The graphical design forces me to make some visual changes to the tab bar - one of them is to have fixed width for the indicator line. I managed to do it this way:

extension PageTabBar  {

  open override func layoutSubviews() {
    super.layoutSubviews()

    let lineWidth = CGFloat(100)

    line.frame = CGRect(x: selected!.x+(selected!.x+(selected!.width-lineWidth)/2), y: .bottom == lineAlignment ? height - lineHeight : 0, width: lineWidth, height: lineHeight)
  }

}

Xcode warns cannot override a non-dynamic class declaration from an extension but it works in runtime. However, this breaks the selection animation and I cannot fix those, since the animate function is declared fileprivate. I would welcome a less cumbersome way to customize.

daniel-jonathan commented 7 years ago

@stachon Please share the design you are trying to accomplish. Thank you!

stachon commented 7 years ago

@danieldahan

snimek obrazovky 2017-06-04 v 16 35 00
stachon commented 7 years ago

I came up with a trick to keep the animation:

extension PageTabBar  {

  open override func layoutSubviews() {
    super.layoutSubviews()

    var line2: UIView
    if line.subviews.count == 0 {
      line2 = UIView()
      line2.backgroundColor = UIColor.white
      line.addSubview(line2)
    } else {
      line2 = line.subviews[0]
    }

    let lineWidth = CGFloat(100)

    line2.frame = CGRect(x: (selected!.width-lineWidth)/2, y: 0, width: lineWidth, height: lineHeight)
  }

}
daniel-jonathan commented 7 years ago

You could add a handler to the button, and there are delegates you can tap into.

@objc(TabBarDelegate)
public protocol TabBarDelegate {
    /**
     A delegation method that is executed when the button will trigger the
     animation to the next tab.
     - Parameter tabBar: A TabBar.
     - Parameter button: A UIButton.
     */
    @objc
    optional func tabBar(tabBar: TabBar, willSelect button: UIButton)

    /**
     A delegation method that is executed when the button did complete the
     animation to the next tab.
     - Parameter tabBar: A TabBar.
     - Parameter button: A UIButton.
     */
    @objc
    optional func tabBar(tabBar: TabBar, didSelect button: UIButton)
}

Have you looked into those?

daniel-jonathan commented 7 years ago

@stachon btw... there is a newly created TabsController that will replace all this with added and missing features. So hopefully that will help solve your issue.

stachon commented 7 years ago

@danieldahan unfortunately TabBarDelegate methods are not triggered for pageTabBar of PageTabBarController. However I can use PageTabBarControllerDelegate. Thank you, looking forward to next release!

daniel-jonathan commented 7 years ago

@stachon sorry, I meant the PageTabBarControllerDelegate. Thanks, I think it will be a good one :)