美文网首页xamarin开发技术
Xamarin.iOS实现中间凸起圆形TabBar

Xamarin.iOS实现中间凸起圆形TabBar

作者: Funky_Xamarin | 来源:发表于2017-06-06 10:23 被阅读206次

    本文主要讲解实现中间凸起的圆形TabBar控制器,使用咸鱼App进行例子参考


    之前在讲解完基本的控件的使用后,一直想讲解下Tabbar的使用,刚好有个机会可以结合凸起的圆形TabBar来讲解下TabBar的基本使用过程,首先我们在讲解TabBar之前,我们先介绍下UITabBarController:

    UITabBarController

    UITabBarController就是一个类似于上面咸鱼显示的视图控制器页面,其可以添加多个控制器进行切换显示;还提供了一个UITabBar类来允许用户进行控制器视图的切换。

    首先我们来基本使用下UITabBarController去构建一个视图页面

    using System;
    using UIKit;
    
    namespace TabbedApplication {
            public class TabController : UITabBarController {
    
                    UIViewController tab1, tab2, tab3;
    
                    public TabController ()
                    {
                            tab1 = new UIViewController();
                            tab1.Title = "Green";
                            tab1.View.BackgroundColor = UIColor.Green;
    
                            tab2 = new UIViewController();
                            tab2.Title = "Orange";
                            tab2.View.BackgroundColor = UIColor.Orange;
    
                            tab3 = new UIViewController();
                            tab3.Title = "Red";
                            tab3.View.BackgroundColor = UIColor.Red;
    
                            var tabs = new UIViewController[] {
                                    tab1, tab2, tab3
                            };
    
                            ViewControllers = tabs;
                    }
            }
    }
    

    其中ViewControllers就是设置UITabBarController 里面的多个视图控制器,设置其的ViewControllers数组,即在底部显示多少个相应的tabbaritem。

    同样我们可以自定义相应的UITabBarItem的样式,已达到相应的业务要求

    tab1.TabBarItem = new UITabBarItem (UITabBarSystemItem.Favorites, 0);
    
    tab2 = new UIViewController ();
    tab2.TabBarItem = new UITabBarItem ();
    tab2.TabBarItem.Image = UIImage.FromFile ("second.png");
    tab2.TabBarItem.Title = "Second";
    tab2.View.BackgroundColor = UIColor.Orange;
    
    tab3.TabBarItem.BadgeValue = "Hi";
    

    这就是基本的UITabBarController的使用,我们可以添加多个控制器,自定义相应的TabBarItem的显示样式,去丰富我们的界面显示元素。


    MYTabBar

    根据了上边的UITabBarController的简单使用介绍,我们发现对于单单使用UITabBarController去实现咸鱼那样凸起的圆形TabBar其实是无法直接实现的,这里我们需要去自定义我们的TabBar试图。

    首先我们先自定义TabBarItem,这里我们称为MYTabBarItem,其本质是一个按钮,我们去重新设置他的图片和文字的显示位置即可

    public enum LLTabBarItemType
        {
            Normal = 0,
            Rise,
        }
    
        public class MYTabBarItem : UIButton
        {
            static public string kLLTabBarItemAttributeType = "MYTabBarItemAttributeType";
            static public string kLLTabBarItemAttributeTitle = "MYTabBarItemAttributeTitle";
            static public string kLLTabBarItemAttributeNormalImageName = "LLTabBarItemAttributeNormalImageName";
            static public string kLLTabBarItemAttributeSelectedImageName = "LLTabBarItemAttributeSelectedImageName";
    
            public LLTabBarItemType tabBarItemType{get;set;}
    
            public MYTabBarItem(CGRect frame) : base(frame)
            {
                if(this != null)
                    config();
            }
    
            public MYTabBarItem()
            {
                if (this != null)
                    config();
            }
    
            private void config()
            { 
                this.AdjustsImageWhenHighlighted = true;
                this.ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;
            }
    public override void LayoutSubviews()
            {
                base.LayoutSubviews();
                this.TitleLabel.SizeToFit();
                CGSize titleSize = this.TitleLabel.Frame.Size;
                UIImage image = this.ImageForState(UIControlState.Normal);
                CGSize imageSize;
                if (image == null)
                {
                    imageSize = new CGSize(0,0);
                }
                else
                {
                    imageSize = this.ImageForState(UIControlState.Normal).Size;
                }
    
                if (imageSize.Width != 0 && imageSize.Height != 0)
                {
                    nfloat imageViewCenterY = this.Frame.Height - 3 - titleSize.Height - imageSize.Height / 2 - 5;
                    this.ImageView.Center = new CGPoint(this.Frame.Width / 2, imageViewCenterY);
                }
                else
                {
                    CGPoint imageViewCenter = this.ImageView.Center;
                    imageViewCenter.X = this.Frame.Width / 2;
                    imageViewCenter.Y = (this.Frame.Height - titleSize.Height) / 2;
                    this.ImageView.Center = imageViewCenter;
                }
    
                CGPoint labelCenter = new CGPoint(this.Frame.Width / 2 ,this.Frame.Height -3 - titleSize.Height/2 );
                this.TitleLabel.Center = labelCenter;
    
                //Console.WriteLine(this.ImageView.Frame);
    
            }
    

    这里我们需要在LayoutSubviews方法里面对按钮的label和image位置进行重新布局,调整label显示在图片的上边。这里我们需要自定义一个属性去区分是否为中间圆形TabBarItem。

    注意事项:
    1、当我们重写LayoutSubviews方法时候,我们千万不能忘记base.LayoutSubviews();如果不添加此行代码无法显示成功。
    2、LayoutSubviews在什么时候调用?1)直接调用[self setNeedsLayout];2)addSubview的时候;3)当view的size发生改变的时候;4)滑动UIScrollView的时候;5)旋转Screen会触发父UIView上的layoutSubviews事件.

    接着我们就可以自定义UITabBar了,这里我们称为MYTabBar

    public class MYTabBar : UIView
        {
            private List<MYTabBarItem> tabBarItems ;
            public List<Dictionary<string,object>> tabBarItemAttributes
            {
                get
                {
                    return _tabBarItemAttributes;
                }
                set
                {
                    _tabBarItemAttributes = value;
                    nfloat normalItemWidth = (UIScreen.MainScreen.Bounds.Width * 3 / 4) / (_tabBarItemAttributes.Count - 1);
                    nfloat tabBarHeight = this.Frame.Height;
                    nfloat publishItemWidth = (UIScreen.MainScreen.Bounds.Width / 4);
    
                    int itemTag = 0;
                    bool passedRiseItem = false;
                    tabBarItems = new List<MYTabBarItem>();
    
                    foreach (var item in _tabBarItemAttributes)
                    {
                        if (item is Dictionary<string, object>)
                        {
                            Dictionary<string, object> itemDic = (Dictionary<string, object>)item;
                            var type = (object)itemDic[MYTabBarItem.kLLTabBarItemAttributeType];
                            CGRect frame = new CGRect(itemTag * normalItemWidth + (passedRiseItem ? publishItemWidth : 0), 0, (type == (object)LLTabBarItemType.Rise ? publishItemWidth : normalItemWidth), tabBarHeight);
    
                            MYTabBarItem tabBarItem = tabbarItemWithProperty(frame,
                                                                             itemDic[MYTabBarItem.kLLTabBarItemAttributeTitle].ToString(),
                                                                             itemDic[MYTabBarItem.kLLTabBarItemAttributeNormalImageName].ToString(),
                                                                             itemDic[MYTabBarItem.kLLTabBarItemAttributeSelectedImageName].ToString(),
                                                                             (LLTabBarItemType)type);
                            
                            if (itemTag == 0)
                            {
                                tabBarItem.Selected = true;
                            }
    
                            tabBarItem.TouchUpInside += (object sender, EventArgs e) =>
                            {
                                if (((MYTabBarItem)sender).tabBarItemType != LLTabBarItemType.Rise)
                                {
                                    setSelectedIndex((int)((MYTabBarItem)sender).Tag);
                                }
                                else
                                {
    
                                }
                            };
                            if (tabBarItem.tabBarItemType != LLTabBarItemType.Rise)
                            {
                                tabBarItem.Tag = itemTag;
                                itemTag++;
                            }
                            else {
                                passedRiseItem = true;
                            }
                            tabBarItems.Add(tabBarItem);
                            this.AddSubview(tabBarItem);
    
                        }
                    }
                }
            }
    
            private List<Dictionary<string, object>> _tabBarItemAttributes;
            public MYTabBar()
            {
            }
    
            public MYTabBar(CGRect frame) : base(frame)
            {
                
            }
    
            private MYTabBarItem tabbarItemWithProperty(CGRect frame ,string title,string normalImageName,string selectedImageName,LLTabBarItemType tabBarItemType)
            {
                MYTabBarItem item = new MYTabBarItem(frame);
                item.SetTitle(title, UIControlState.Normal);
                item.SetTitle(title, UIControlState.Selected);
                item.TitleLabel.Font = UIFont.SystemFontOfSize(8);
                UIImage normalImage = UIImage.FromBundle(normalImageName);
                UIImage selectedImage = UIImage.FromBundle(selectedImageName);
                item.SetImage(normalImage , UIControlState.Normal);
                item.SetImage(selectedImage , UIControlState.Selected);
                item.SetTitleColor(UIColor.FromWhiteAlpha(51/255,1), UIControlState.Normal);
                item.SetTitleColor(UIColor.FromWhiteAlpha(51 / 255, 1), UIControlState.Selected);
                item.tabBarItemType = tabBarItemType;
                return item;
            }
    
            private void setSelectedIndex(int index)
            { 
                foreach(MYTabBarItem item in tabBarItems)
                {
                    if (item.Tag == index)
                    {
                        item.Selected = true;
                    }
                    else {
                        item.Selected = false;
                    }
                }
    
                UIWindow keyWindow = UIApplication.SharedApplication.Delegate.GetWindow();
                UITabBarController tabBarController = (UITabBarController)keyWindow.RootViewController;
                if (tabBarController!=null)
                {
                    tabBarController.SelectedIndex = index;
                }
            }
    
        }
    

    在这里我们需要根据输入的字典数组去设置每个MYTabBarItem的属性,然后根据其类型去设置相应的frame,而且绑定不同的事件。

    接着我们去AppDelegate文件中去设置根控制器

    Window = new UIWindow(UIScreen.MainScreen.Bounds);
                Window.BackgroundColor = UIColor.White;
    
    
                UICollectionViewFlowLayout layout = new UICollectionViewFlowLayout();
                layout.ItemSize = new CGSize(UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height);
                layout.MinimumLineSpacing = 0;
                layout.ScrollDirection = UICollectionViewScrollDirection.Horizontal;
                UICollectionViewController guideVC = new ViewController(layout);
    
                MyViewController vc = new MyViewController();
                Slide sc = new Slide();
    
                UITabBarController tabbar = new UITabBarController();
                tabbar.ViewControllers = new UIViewController[] {vc, sc,guideVC,vc,sc};
                UITabBar.Appearance.BackgroundImage = new UIImage();
                UITabBar.Appearance.ShadowImage = new UIImage();
    
                MYTabBar tab = new MYTabBar(tabbar.TabBar.Bounds);
                if (MYTabBarItem.kLLTabBarItemAttributeTitle != null)
                {
                    var key1 = MYTabBarItem.kLLTabBarItemAttributeTitle;
                    var key2 = MYTabBarItem.kLLTabBarItemAttributeType;
                    var key3 = MYTabBarItem.kLLTabBarItemAttributeNormalImageName;
                    var key4 = MYTabBarItem.kLLTabBarItemAttributeSelectedImageName;
    
                    var value2 = LLTabBarItemType.Normal;
                    var value1 = LLTabBarItemType.Rise;
    
                    var dict1 = new Dictionary<string, object>();
                    dict1.Add(key1,"首页");
                    dict1.Add(key2, value2);
                    dict1.Add(key3, "home_normal");
                    dict1.Add(key4, "home_highlight");
    
                    var dict2 = new Dictionary<string, object>();
                    dict2.Add(key1, "同城");
                    dict2.Add(key2, value2);
                    dict2.Add(key3, "mycity_normal");
                    dict2.Add(key4, "mycity_highlight");
    
                    var dict3 = new Dictionary<string, object>();
                    dict3.Add(key1, "发布");
                    dict3.Add(key2, value1);
                    dict3.Add(key3, "post_normal");
                    dict3.Add(key4, "post_highlight");
    
                    var dict4 = new Dictionary<string, object>();
                    dict4.Add(key1, "消息");
                    dict4.Add(key2, value2);
                    dict4.Add(key3, "message_normal");
                    dict4.Add(key4, "message_highlight");
    
                    var dict5 = new Dictionary<string, object>();
                    dict5.Add(key1, "我的");
                    dict5.Add(key2, value2);
                    dict5.Add(key3, "account_normal");
                    dict5.Add(key4, "account_highlight");
    
                    tab.tabBarItemAttributes = new List<Dictionary<string, object>>() {dict1,dict2,dict3,dict4,dict5 } ;
                }
    
                tabbar.TabBar.AddSubview(tab);
                Window.RootViewController = tabbar;
                Window.MakeKeyAndVisible();
    

    最后这个自定义的TabBar就这样完成了,项目实例源码在github上

    到这里Xamarin.iOS中实现中间凸起圆形TabBar的介绍就完成了,希望能对您有所帮助。

    ——End 有问题可以加我微信,大家一起讨论

    相关文章

      网友评论

        本文标题:Xamarin.iOS实现中间凸起圆形TabBar

        本文链接:https://www.haomeiwen.com/subject/bzuwfxtx.html