Xamarin.iOS 自訂按鈕選取器

來源:互聯網
上載者:User

最近項目中做了一個標題列中的按鈕選取器,原生的UISegmentedControl 無法達到項目效果,效果如下圖:

如果只針對項目寫一個不難,可是如果以後遇到了還需要針對項目再去寫一個,於是我打算把他寫的活一些,最終決定用Builder模式來完成它,以前做android原生的時候就用Builder模式構建了一些組合view,但是我嘗試著用java的方式去Builder的時候發現行不通,這次是Xamarin的項目,語言是C#,於是我又去學習了一下C#的Builder模式(淺顯的理解很簡單)。

哦,差點忘了介紹,項目的架構是MvvmCross,不理解的同學去他的官網看看,很良心的。

最終計划了一下這個工作分為三步走(典型的面向過程,哈哈)。



第一步:將這些可以看見的屬性,或者隨時可以變的屬性抽象出來。

using System;using UIKit;namespace RuilaiGrow.iOS{    /// <summary>    /// 多按鈕圓角view構建抽象類別    /// by ge    /// </summary>    abstract class BuilderTopSelectedTitle    {        public abstract void setTitles(string[] titles);        public abstract void setTextSize(nfloat size);        public abstract void setCornerRadius(nfloat radius);        public abstract void setHeight(nfloat height);        public abstract void setWidth(nfloat width);        public abstract void setNormalTextColor(UIColor color);        public abstract void setSelectedTextColor(UIColor color);        public abstract void setViewBackground(UIColor background);        public abstract void setItemNormal(UIColor corlor);        public abstract void setItemSelected(UIColor selected);        public abstract UIView create();    }}


項目比較緊張,可能這些屬性還是不夠,或者說想的不到位,以後慢慢添加和最佳化。


第二步:建立實作類別,構建需要的控制項。

經過一番研究,最外層(也就是最終建立返回給介面的)是一個UIView,中間的按鈕用UIButton來代替,原因是:經過查閱資料,和嘗試,發現UIButton是將UILable於UIImageView封裝的結果,採用懶載入的方式,用誰初始化誰,感覺很棒不用我自己造輪子了(以前一直做android原生,對iOS不是很瞭解,大家見笑)。下面是實作類別的代碼,注視挺全的了,直接複製粘貼了(懶懶懶)。

using System;using System.Drawing;using RuilaiGrow.iOS.Common;using UIKit;namespace RuilaiGrow.iOS{    /// <summary>    /// 知識庫首頁標題切換控制器    /// </summary>    class KnowledgeTitleControl : BuilderTopSelectedTitle    {        public KnowledgeTitleControl()        {                    }        //最外層總view        UIView _thisView = null;        public UIView ThisView        {            get            {                if (_thisView == null)                {                    //根據本view的寬與高來計算其實位置(目的最終添加到View的導覽列的時候可以置中顯示)                    nfloat startX = (UIScreen.MainScreen.Bounds.Width - _itemWid * _titles.Length) / 2;                    nfloat startY = (EasyLayout.BarHeight - _viewHei) / 2;                    _thisView = new UIView(new RectangleF((float)startX, (float)startY, (float(_itemWid * _titles.Length), (float)_viewHei));                    _thisView.BackgroundColor = _viewBackground;                }                return _thisView;            }        }        //標題數組        private string[] _titles;        //item數組        private UIButton[] _itemBtns;        //控制項的高        private nfloat _viewHei = 45;        //item的寬        private nfloat _itemWid = 70;        //item正常時的顏色        private UIColor _itemNormalBac = UIColor.Blue;        //item選中時的顏色        private UIColor _itemSeletedBac = UIColor.White;        //文字正常的顏色        private UIColor _textNormalColor = UIColor.Black;        //文字選中時的顏色        private UIColor _textSeletedColor = UIColor.Red;        //設定本view的顏色        private UIColor _viewBackground = UIColor.Blue;        //文字的大小        private nfloat _textSize = 15;        //邊框與按鈕的圓角        private nfloat _radius = 18;        //按鈕上次點擊事件 預設0        private int lastIndex = 0;        /// <summary>        /// 最終建立view        /// </summary>        public override UIView create()        {            ThisView.Layer.BorderWidth = 1;            ThisView.Layer.BorderColor = MvxTouchColor.ShallowGrayOne.CGColor;            ThisView.Layer.CornerRadius = _radius;            _itemBtns = new UIButton[_titles.Length];            //迴圈建立文字按鈕並加入到總view中            int lenght = _titles.Length;            for (int i = 0; i < lenght; i++) {                _itemBtns[i] = new UIButton();                _itemBtns[i].Tag = i;                _itemBtns[i].SetTitle(_titles[i], UIControlState.Normal);                _itemBtns[i].SetTitleColor(_textNormalColor, UIControlState.Normal);                _itemBtns[i].Layer.CornerRadius = _radius;                _itemBtns[i].TitleLabel.Font = UIFont.SystemFontOfSize(_textSize);//設定第一個按鈕選中狀態                if (i == 0)                {                    _itemBtns[i].BackgroundColor = _itemSeletedBac;                    _itemBtns[i].SetTitleColor(_textSeletedColor, UIControlState.Normal);                }            }            ThisView.AddSubviews(_itemBtns);            //迴圈設定view內部item之間約束            for (int i = 0; i < lenght; i++) {                if (i == 0)                {                    ThisView.ConstrainLayout(() =>                                             _itemBtns[i].Frame.GetCenterY() == ThisView.Frame.GetCenterY()                                             && _itemBtns[i].Frame.Width == _itemWid                                             && _itemBtns[i].Frame.Height == ThisView.Frame.Height                                             && _itemBtns[i].Frame.Left == ThisView.Frame.Left                                             && ThisView.Frame.Bottom == _itemBtns[i].Frame.Bottom                                        );                }                else {                     ThisView.ConstrainLayout(() =>                                             _itemBtns[i].Frame.GetCenterY() == ThisView.Frame.GetCenterY()                                             && _itemBtns[i].Frame.Left == _itemBtns[i - 1].Frame.Right                                             && _itemBtns[i].Frame.Width == _itemWid                                             && _itemBtns[i].Frame.Height == ThisView.Frame.Height                                        );                }            }            //按鈕點擊事件            for (int i = 0; i < _titles.Length; i++) {                _itemBtns[i].TouchUpInside += this.TouchBtn;            }            return ThisView;        }        //按鈕點擊處理        private void TouchBtn(object sender, EventArgs e)        {            UIButton v = (UIKit.UIButton)sender;            //如果和上次點的一樣 return            if (v.Tag == lastIndex)                return;            //清空上次點擊view的狀態            _itemBtns[lastIndex].BackgroundColor = _itemNormalBac;            _itemBtns[lastIndex].SetTitleColor(_textNormalColor, UIControlState.Normal);            //設定本次點擊的view的狀態            _itemBtns[v.Tag].BackgroundColor = _itemSeletedBac;            _itemBtns[v.Tag].SetTitleColor(_textSeletedColor, UIControlState.Normal);            //記錄本次點擊的位置            lastIndex = (int)v.Tag;            //回調點擊位置            if (_click != null) {                _click.TitleBackIndex((int)v.Tag);            }        }        /// <summary>        /// 設定按鈕正常時的狀態顏色        /// </summary>        /// <param name="corlor">Corlor.</param>        public override void setItemNormal(UIColor corlor)        {            this._itemNormalBac = corlor;        }        /// <summary>        /// 設定item選中時的背景        /// </summary>        /// <param name="selected">Selected.</param>        public override void setItemSelected(UIColor selected)        {            this._itemSeletedBac = selected;        }        /// <summary>        /// 設定正常時的文字的顏色        /// </summary>        /// <param name="color">Color.</param>        public override void setNormalTextColor(UIColor color)        {            this._textNormalColor = color;        }        /// <summary>        /// 設定選中時文字的顏色        /// </summary>        /// <param name="color">Color.</param>        public override void setSelectedTextColor(UIColor color)        {            this._textSeletedColor = color;        }        /// <summary>        /// 設定item的文字        /// </summary>        /// <param name="titles">Titles.</param>        public override void setTitles(string[] titles)        {            this._titles = titles;        }        /// <summary>        /// 設定view的背景圖片        /// </summary>        /// <param name="background">Background.</param>        public override void setViewBackground(UIColor background)        {            this._viewBackground = background;        }        /// <summary>        /// 設定item的寬        /// </summary>        /// <param name="width">Width.</param>        public override void setWidth(nfloat width)        {            this._itemWid = width;        }        /// <summary>        /// 設定本view的高        /// </summary>        /// <param name="height">Height.</param>        public override void setHeight(nfloat height)        {            this._viewHei = height;        }        /// <summary>        /// 設定邊框的圓角與按鈕的圓角        /// </summary>        /// <param name="radius">Radius.</param>        public override void setCornerRadius(nfloat radius)        {            this._radius = radius;        }        /// <summary>        /// 設定文字的大小        /// </summary>        /// <param name="size">Size.</param>        public override void setTextSize(nfloat size)        {            this._textSize = size;        }        /// <summary>        /// 點擊view回調介面        /// </summary>        public interface ClickTitleControlItem {            void TitleBackIndex(int index);        }        private ClickTitleControlItem _click;        public void setClickTitleControlItem(ClickTitleControlItem click)        {            this._click = click;        }        }}



上面就是實作類別的全部內容,最後那個介面是這個view點擊某個按鈕時的回調,同事說我這是拿java的思想來寫c#,搞得我去查了一下,打算把這個換成事件委託機制。

下面看一下第三步:使用

在Controller中直接定義一個UIView接收建立的view就可以:

       

 //頭部導覽列的view        UIView _topViewControl = null;        public UIView TopViewControl {             get{                if (_topViewControl == null) {                    string[] s = new string[] {                        "0-1歲", "1-3歲", "3-6歲"                    };                    KnowledgeTitleControl ctr = new KnowledgeTitleControl();                    ctr.setWidth(85);                    ctr.setHeight(EasyLayout.BarHeight - 10f);                    ctr.setTitles(s);                    ctr.setTextSize(15);                    ctr.setCornerRadius(18);                    ctr.setItemNormal(MvxTouchColor.DeepRed);                    ctr.setViewBackground(MvxTouchColor.DeepRed);                    ctr.setItemSelected(MvxTouchColor.White);                    ctr.setNormalTextColor(MvxTouchColor.ShallowGrayOne);                    ctr.setSelectedTextColor(MvxTouchColor.DeepRed);                    ctr.setClickTitleControlItem(this);                    _topViewControl = ctr.create();                }                return _topViewControl;            }        }



最後將view添加到導覽列就可以了:

在ViewDidLoad()方法中:

//將頭部控制器的uiview加入頂部導覽列NavigationController.NavigationBar.AddSubview(TopViewControl);

按鈕的個數是根據建構函式傳入的數組決定的。

搞定。。




相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.