Unity 之 模拟滑动日历选择日期简例 (文末源码)

2021-03-19 10:28发布

Unity 制作一个用于选择日期的小例子,,,

【经实践,此方式并不是很好,交互感很低(2019.02.23)推荐看下Demo2】

下面以选择月份为例:


搭建如下场景,,,对图中标记的地方的简要说明:SelectBg:模拟选中的当前日期,

month:做作为挂载脚本的物体,挂载Image组件将其透明度调为:0,,,然后创建其子物体,只挂载Text组件用于显示文字,并且为其命名1,2,3,4,5,,,以后获取的时候可以通过month.transform.getChild(2).GetComponent ().text --获取这个字符串的前两位

就是所选择的变量了,

完整代码如下:都需要挂载到month上,,,

【另:需把子物体的Text组件上的Raycast Target选项取消勾选,,,脚本不能挂载多个物体,使用多个是需代码移除和加载,】
如选择年月日不需分开,则可使用同一个物体下扩展,参考链接

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.EventSystems;

using UnityEngine.UI;


/// <summary>

/// 日历

/// </summary>

public class Rili : MonoBehaviour, IPointerDownHandler

{

    public static Rili Singleton;


    public GameObject go;

    private List<GameObject> monthList = new List<GameObject>();

    public static int yearValue = 1;

    public static int monthValue = 1;

    public static int dayValue = 1;

    public static int hourValue = 1;

    public static int minValue = 1;


    private int curtime; //当前显示时间

    private int isClickDownNum;   //点击次数

    public bool isCanDrag = true; //是否可拖动(避免其他文字隐藏时可以拖动)


    void Awake()

    {

        Singleton = this;    

    }


    void Start()

    {

        go = this.gameObject;

        curtime = int.Parse(this.transform.GetChild(2).GetComponent<Text>().text.Substring(0, 2));

        //Debug.Log(go.name + "...日历选择的初始化操作............" + curtime);

    

        isClickDownNum = 1;

        for (int i = 0; i < this.transform.childCount; i++)

        {

            this.transform.GetChild(i).gameObject.SetActive(false);

        }

        this.transform.GetChild(2).gameObject.SetActive(true);      

      

        Init();

        UpdateTime();

     

        //Debug.Log(go.name + "...日历选择的初始化操作............" + this.transform.GetChild(2).GetComponent<Text>().text);

    }


    /// <summary>

    /// 初始化

    /// </summary>

    public void Init()

    {

    //可以获取当前时间或者上传编辑时间

        yearValue = System.DateTime.Now.Year;

        monthValue = curtime;

        dayValue = curtime;

        hourValue = curtime;

        minValue = curtime;


        foreach (Transform item in go.transform)

        {

            monthList.Add(item.gameObject);

            item.gameObject.SetActive(true);

        }


        foreach (GameObject item in monthList)

        {

            string n = item.name;

            float alpha = 1 - ((Mathf.Abs(3.0f - float.Parse(n)))) / 3;

            item.gameObject.GetComponent<Text>().color = new Color(item.GetComponent<Text>().color.r, item.GetComponent<Text>().color.r, item.GetComponent<Text>().color.r, alpha);

            item.GetComponent<Text>().fontSize = 32 - Mathf.Abs(3 - int.Parse(n));

        }       

    }   

    

    /// <summary>

    /// 隐藏其他显示在外面的时间文字

    /// </summary>

    public void HideOther()

    {

        for (int i = 0; i < this.transform.childCount; i++)

        {

            this.transform.GetChild(i).gameObject.SetActive(false);

        }

        this.transform.GetChild(2).gameObject.SetActive(true);

    } 


    /// <summary>

    /// 更新显示时间

    /// </summary>

    public void UpdateTime()

    {

        if (go.name == "year")

        {

            foreach (GameObject go in monthList)

            {

                int nn = int.Parse(go.name);

                go.GetComponent<Text>().text = (nn - 3 + yearValue).ToString().Substring(2, 2) + "年";

            }

        }


        if (go.name == "month")

        {

            foreach (GameObject go in monthList)

            {

                int nn = int.Parse(go.name);

                int mm = Mathf.Abs(nn + monthValue - 3); 

                if (mm % 12 == 0)

                {

                    go.GetComponent<Text>().text = "12月";

                }

                else

                {

                    go.GetComponent<Text>().text = (Mathf.Abs(mm % 12) >= 10 ? Mathf.Abs(mm % 12).ToString() : "0" + Mathf.Abs(mm % 12)) + "月";

                }

            }

        }


        if (go.name == "day")

        {          

            foreach (GameObject go in monthList)

            {

                int nn = int.Parse(go.name);

                int mm = Mathf.Abs(nn + dayValue - 3);

                //编辑月份和年份时存储的当前月&年  使用PlayerPrefs.SetInt("PGMatchMonth",Value); 保存

                int dd = GetDayCount(PlayerPrefs.GetInt("PGMatchMonth"), PlayerPrefs.GetInt("PGMatchYear"));

                //Debug.Log(nn + "....mm.." + mm + "... dd.." + dd);

                if (mm % dd == 0)

                {

                    go.GetComponent<Text>().text = dd + "日";

                }

                else

                {

                    go.GetComponent<Text>().text = ((mm % dd >= 10) ? (mm % dd).ToString() : "0" + (mm % dd))+ "日";

                }

            }

        }


        if (go.name == "hour")

        {

            foreach (GameObject go in monthList)

            {

                int nn = int.Parse(go.name);

                int mm = nn + hourValue - 3;

                int hour = 24;

                //Debug.Log("nn"+ nn + "... mm" + mm+ "...minValue % hour"+ minValue % hour);

                if (mm % hour == 0)

                {

                    go.GetComponent<Text>().text = "00时";

                }

                else

                {

                    go.GetComponent<Text>().text = (Mathf.Abs(mm % hour) >= 10 ? (Mathf.Abs(mm % hour).ToString()) : "0" + Mathf.Abs(mm % hour)) + "时";

                }

            }

        }


        if (go.name == "min")

        {

            foreach (GameObject go in monthList)

            {

                int nn = int.Parse(go.name);

                int mm = nn + minValue - 3;

                if (mm % 60 == 0)

                {

                    go.GetComponent<Text>().text = "00分";

                }

                else

                {

                    go.GetComponent<Text>().text = (Mathf.Abs(mm % 60) >= 10 ? (Mathf.Abs(mm % 60).ToString()) : "0" + Mathf.Abs(mm % 60)) + "分";

                }

            }

        }

    }


    public void OnPointerDown(PointerEventData eventData)

    {

        Debug.Log("OnPointerDown...>>>>>>>>>>>>>>>>>> " + isClickDownNum);

        if (isClickDownNum == 1)

        {

            monthList.Clear();

            Init();

            isCanDrag = true;

        }

        else if (isClickDownNum == 2)

        {

            isCanDrag = true;

        }

        else if (isClickDownNum == 3)

        {            

            for (int i = 0; i < this.transform.childCount; i++)

            {

                this.transform.GetChild(i).gameObject.SetActive(false);

            }

            this.transform.GetChild(2).gameObject.SetActive(true);

            isClickDownNum = 0;

            isCanDrag = false;

        }

        isClickDownNum++;

    }      


    //返回有几天

    int GetDayCount(int month,int year)

    {

        //不符合条件的默认查的是1月

        if (month > 12 || month < 1) return 31;

        //是否是闰年,当前只用2019,  

        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))

        {

            if (month == 2) return 29;

        }

        else

        {

            if (month == 2) return 28;

        }

        switch (month)

        {

            case 1:

            case 3:

            case 5:

            case 7:

            case 8:

            case 10:

            case 12:

                return 31;

            case 4:

            case 6:

            case 9:

            case 11:

                return 30;

            default:break;

        }

        return 31;     

    }

}


using System;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.EventSystems;


/// <summary>

///日期选择模拟拖动效果

/// </summary>

public class RiLiMove : MonoBehaviour,IPointerDownHandler, IPointerUpHandler

{

    public GameObject go;

    private string name;

    private bool isDown = false;

    Vector3 mouseDown_Pos;       //首次按下坐标

    Vector3 atDown_Pos;          //当前按下坐标   

    float distance = 0;          //距离 差值

    private float self_y;        //当前对象的y值


    void Awake () {

        go = this.gameObject;

        self_y = GetComponent<RectTransform>().localPosition.y;

        name = go.name;

}

// Update is called once per frame

void Update () {

        if (isDown && Rili.Singleton.isCanDrag)

        {

            atDown_Pos = Input.mousePosition;

            distance = atDown_Pos.y - mouseDown_Pos.y;

            mouseDown_Pos = atDown_Pos;


            go.GetComponent<RectTransform>().localPosition += new Vector3(0, distance, 0);


            if (Mathf.Abs(self_y - GetComponent<RectTransform>().localPosition.y) >= 5)

            {

                //Debug.Log(self_y + "  ... " +GetComponent<RectTransform>().localPosition.y);

                if (self_y - GetComponent<RectTransform>().localPosition.y < 0)

                {

                    if (name == "year")

                        Rili.yearValue += 1;                    

                    if (name == "month")

                        Rili.monthValue += 1;

                    if (name == "day")

                        Rili.dayValue += 1;

                    if (name == "hour")

                        Rili.hourValue += 1;

                    if (name == "min")

                        Rili.minValue += 1;

                }

                else

                {

                    if (name == "year")

                        Rili.yearValue -= 1;

                    if (name == "month")

                        Rili.monthValue -= 1;

                    if (name == "day")

                        Rili.dayValue -= 1;

                    if (name == "hour")

                        Rili.hourValue -= 1;

                    if (name == "min")

                        Rili.minValue -= 1;

                }

            }

            Rili.Singleton.UpdateTime();

            go.GetComponent<RectTransform>().localPosition = new Vector3(go.GetComponent<RectTransform>().localPosition.x, self_y);

        }

       

    }


    public void OnPointerDown(PointerEventData eventData)

    {

        //Debug.Log("RiLiMove OnPointerDown ... <<<<<<<<<" + name);

        mouseDown_Pos = Input.mousePosition;

        isDown = true;

    }


    public void OnPointerUp(PointerEventData eventData)

    {

        //Debug.Log("RiLiMove OnPointerUp ... >>>>>>>>>" + name);

        isDown = false;

    }

}


看看效果图吧:

需要源码的童鞋可以点击链接下载



Demo2:
下载链接
讲解地址

没有积分的同学可以V信搜"开发同学留步"或者扫描主页左侧二维码,回复“日历”获得两个Demo项目源码。




————————————————

版权声明:本文为CSDN博主「妳是我改卟了的bug」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Czhenya/article/details/86629460