Closed Seb-AS closed 7 years ago
@Seb-AS Hi, This isn't possible out of the box, But i'll see if I can find a hack for you.
@Minitour Thanks
@Seb-AS Are you planning to have a controller in the middle? or you are using it for a custom action?
@Minitour yes, the idea it's to go home when the user taps on the round tabBar item.
Another question: its possible to not tint that tabbar item?, because it'll have a logo with a few colors and when its loaded to the tabbar are overrided by tabController.defaultColor.
thanks
To use icons with multi color patterns use:
tabBar.ignoreIconColors = true
@Minitour cool!
Hi again @Seb-AS, Sorry for the late response, I was quite busy the last few days. Anyways Here is a solution for your problem:
First you need to modify the AZTabBarController.swift
:
Let's start by adding this extension:
public extension AZTabBarController{
public var buttonsContainerView: UIView? {
return buttonsContainer
}
}
Now let's add this new Delegate method to the AZTabBarDelegate
protocol:
public protocol AZTabBarDelegate: class {
...
func tabBar(_ tabBar: AZTabBarController, didSetupButtonAtIndex index: Int, button: UIButton)
}
Add it to the AZTabBarDelegate
extension to make it optional:
public extension AZTabBarDelegate{
...
func tabBar(_ tabBar: AZTabBarController, didSetupButtonAtIndex index: Int, button: UIButton){}
}
we'll need this delegate method to disable the button.
In the setupButtons
function, add the line:
self.delegate?.tabBar(self, didSetupButtonAtIndex: i, button: button)
It should look something like this:
private func setupButtons(){
if self.buttons == nil {
self.buttons = NSMutableArray(capacity: self.tabIcons.count)
for i in 0 ..< self.tabIcons.count {
let button:UIButton = self.createButton(forIndex: i)
self.buttonsContainer.addSubview(button)
self.buttons[i] = button
--------> self.delegate?.tabBar(self, didSetupButtonAtIndex: i, button: button)
}
self.setupButtonsConstraints()
}
self.customizeButtons()
self.buttonsContainer.backgroundColor = self.buttonsBackgroundColor != nil ? self.buttonsBackgroundColor : UIColor.lightGray
}
After you have initialized your controller and setup all the tabs it's time to setup the button:
First let's implement the delegate method we added:
extension ViewController: AZTabBarDelegate{
...
func tabBar(_ tabBar: AZTabBarController, didSetupButtonAtIndex index: Int, button: UIButton) {
if index == 2 {
button.isHidden = true
button.isEnabled = false
}
}
}
Add a Target Function
func didSelectMiddleMenu(sender: UIButton){
tabController.setIndex(2, animated: true)
}
viewDidLoad
where you setup your controller, add the following code:Create the Button
var button = RoundedButton()
button.isEnabled = true
button.backgroundColor = .white
button.translatesAutoresizingMaskIntoConstraints = false
button.setImage(#imageLiteral(resourceName: "ic_phone"), for: [])
button.tintColor = #colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1)
button.addTarget(self, action: #selector(didSelectMiddleMenu(sender:)), for: .touchUpInside)
tabController.view.addSubview(button)
let container = tabController.buttonsContainerView!
button.topAnchor.constraint(equalTo: container.topAnchor, constant: -20).isActive = true
button.heightAnchor.constraint(equalTo: container.heightAnchor, multiplier: 1.1).isActive = true
button.widthAnchor.constraint(equalTo: button.heightAnchor, multiplier: 1.0).isActive = true
button.centerXAnchor.constraint(equalTo: tabController.view.centerXAnchor).isActive = true
container.layer.shadowOffset = CGSize(width: 0, height: -2)
container.layer.shadowRadius = 10
container.layer.shadowOpacity = 0.1
container.layer.shadowColor = UIColor.black.cgColor
tabController.animateTabChange = true
tabController.tabBarHeight = 60
tabController.selectionIndicatorHeight = 3
tabController.selectionIndicatorColor = #colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1)
Here is the Custom UIButton Class I created:
class RoundedButton: UIButton{
override var backgroundColor: UIColor?{
get{
return UIColor(cgColor: layer.backgroundColor ?? UIColor.clear.cgColor)
}set{
layer.backgroundColor = newValue?.cgColor
}
}
open var transformScale: CGFloat = 0.9
private var didSetupDesign = false
override func layoutSubviews() {
super.layoutSubviews()
if !didSetupDesign{
didSetupDesign = true
design()
}
}
func design(){
layer.cornerRadius = frame.size.height/2
layer.shadowOffset = CGSize(width: 0, height: 0)
layer.shadowRadius = 7
layer.shadowOpacity = 0.1
layer.shadowColor = UIColor.black.cgColor
}
override var isHighlighted: Bool{
set{
UIView.animate(withDuration: 0.1) { [weak self] in
let scale = self?.transformScale ?? 0.9
self?.transform = newValue ? CGAffineTransform(scaleX: scale, y: scale) : .identity
}
super.isHighlighted = newValue
}get{
return super.isHighlighted
}
}
}
If you have any further questions feel free to ask
That's great @Minitour, I'll take a look. Thanks for your hard work!
@Seb-AS Did you manage to achieve what you were looking for? If you want I can make a branch.
@Minitour yes, thanks, everything works excellent I've another question because I don't see a way to control the indicator line width and y position.
@Seb-AS I actually did apply the effect you were looking for however I forgot to post it. anyways here it is:
To the extension we have created previously add this function:
public extension AZTabBarController{
public var buttonsContainerView: UIView? {
return buttonsContainer
}
public var selectionIndicatorView: UIView?{
return selectionIndicator
}
}
Then in the viewDidLoad
add these lines of code:
tabController.selectionIndicatorHeight = 10.5
tabController.selectionIndicatorColor = .clear
let indicatorView = tabController.selectionIndicatorView
let subIndicatorView = SubIndicatorView()
subIndicatorView.backgroundColor = #colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1)
subIndicatorView.translatesAutoresizingMaskIntoConstraints = false
indicatorView?.addSubview(subIndicatorView)
subIndicatorView.widthAnchor.constraint(equalTo: subIndicatorView.heightAnchor, multiplier: 5.0).isActive = true
subIndicatorView.heightAnchor.constraint(equalTo: indicatorView!.heightAnchor, multiplier: 0.33).isActive = true
subIndicatorView.centerXAnchor.constraint(equalTo: indicatorView!.centerXAnchor).isActive = true
subIndicatorView.topAnchor.constraint(equalTo: indicatorView!.topAnchor).isActive = true
Here is the class for the SubIndicatorView:
class SubIndicatorView: UIView{
override var backgroundColor: UIColor?{
get{
return UIColor(cgColor: layer.backgroundColor ?? UIColor.clear.cgColor)
}set{
layer.backgroundColor = newValue?.cgColor
}
}
private var didSetupDesign = false
override func layoutSubviews() {
super.layoutSubviews()
if !didSetupDesign{
didSetupDesign = true
design()
}
}
func design(){
layer.cornerRadius = frame.size.height/2
layer.shadowOffset = CGSize(width: 0, height: 0)
layer.shadowRadius = 3
layer.shadowOpacity = 0.7
layer.shadowColor = #colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1).cgColor
layer.masksToBounds = false
}
}
The final result should look something like this:
@Seb-AS Did you get it to work?
@Minitour thanks for the code, I tested but I got a crash in
let indicatorView = tabController.selectionIndicatorView
subIndicatorView.heightAnchor.constraint(equalTo: indicatorView!.heightAnchor, multiplier: 0.33).isActive = true
Looks like indicatorView is nil
Yeah I forgot I modified some other stuff in the class. Here are the extra changes you need to apply in order for this to work.
Make selectionIndicator lazy:
internal lazy var selectionIndicator: UIView = UIView()
Update the setupSelectionIndicator
function:
private func setupSelectionIndicator() {
self.selectionIndicator.translatesAutoresizingMaskIntoConstraints = false
self.buttonsContainer.addSubview(self.selectionIndicator)
self.setupSelectionIndicatorConstraints()
self.selectionIndicatorHeightConstraint.constant = self.selectionIndicatorHeight
self.selectionIndicator.backgroundColor = self.selectionIndicatorColor ?? UIColor.black
}
@Minitour works!!! Thank you so much for all your help.
@Seb-AS You're welcome 😄
Is there a separate branch for this ?
@Abhishekg219 No, but these changes are made on release 1.1.3
, so what you can do is create a branch there and follow the guide.
After following the process above, this is the result on iPhone X on release 1.3.2
. Is there any optimization for this?
I want to make something like the image.
thanks