hch
2025-06-19 35f08360f1e07c7a8301f7b2031c0779e2998fb5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using UnityEngine;
 
[ExecuteAlways]
[RequireComponent(typeof(RectTransform))]
public class SafeAreaUI : MonoBehaviour
{
 
    public const int SafeWidth = 75;
    public const int SafeBottom = 15;   //竖屏下方间隔
 
    public enum SimDevice { None, IphoneX }
    public static SimDevice Sim
    {
        set { LocalSave.SetInt("SimDevice", (int)value); }
        get { return (SimDevice)LocalSave.GetInt("SimDevice"); }
    }
 
    Rect[] NSA_IphoneX = new Rect[]
    {
        new Rect (0f, 102f / 2436f, 1f, 2202f / 2436f),  // Portrait
        new Rect (132f / 2436f, 63f / 1125f, 2172f / 2436f, 1062f / 1125f)  // Landscape
    };
 
    RectTransform _Panel;
    Rect LastSafeArea = new Rect(0, 0, 0, 0);
    Rect LastRect = new Rect(0, 0, 0, 0);
 
    RectTransform Panel
    {
        get
        {
            if (_Panel == null)
                _Panel = GetComponent<RectTransform>();
            return _Panel;
        }
    }
 
    void Awake()
    {
        Refresh();
    }
 
    void Update()
    {
        Refresh();
    }
 
    void Refresh()
    {
        // Rect safeArea = GetSafeArea();
        // if (safeArea != LastSafeArea || LastRect != Panel.rect)
        if (LastRect != Panel.rect)
            ApplySafeArea();
    }
 
    public void ApplySafeArea()
    {
        Panel.anchorMin = Vector2.zero;
        Panel.anchorMax = Vector2.one;
        //竖屏
        if (Screen.height > Screen.width)
        {
            if (Screen.height / Screen.width > 1.8)//宽屏需要适配
            {
                //上下各间隔SafeWidth
                Panel.offsetMin = new Vector2(0, SafeBottom);
                Panel.offsetMax = new Vector2(0, -SafeWidth);
            }
            else
            {
                Panel.offsetMin = new Vector2(0, 0);
                Panel.offsetMax = new Vector2(0, 0);
            }
        }
        else
        {//横屏
            if (Screen.width / Screen.height > 1.8)//宽屏需要适配
            {
                //两边各间隔SafeWidth
                Panel.offsetMin = new Vector2(SafeWidth, 0);
                Panel.offsetMax = new Vector2(-SafeWidth, 0);
            }
            else
            {
                Panel.offsetMin = new Vector2(0, 0);
                Panel.offsetMax = new Vector2(0, 0);
            }
        }
        LastRect = Panel.rect;
    }
    #region 系统api的安全区
    Rect GetSafeArea()
    {
        if (!Application.isEditor)
            return Screen.safeArea;
 
        Rect safeArea = Screen.safeArea;
 
        if (Sim != SimDevice.None)
        {
            Rect nsa = new Rect(0, 0, Screen.width, Screen.height);
 
            switch (Sim)
            {
                case SimDevice.IphoneX:
                    if (Screen.height > Screen.width)  // Portrait
                        nsa = NSA_IphoneX[0];
                    else  // Landscape
                        nsa = NSA_IphoneX[1];
                    break;
                default:
                    break;
            }
 
            safeArea = new Rect(Screen.width * nsa.x, Screen.height * nsa.y, Screen.width * nsa.width, Screen.height * nsa.height);
        }
        return safeArea;
 
    }
 
    void ApplySafeArea(Rect safeArea)
    {
        Debug.LogFormat("ApplySafeArea:{0} ; rect:{1}", safeArea, Panel.rect);
 
        Panel.anchorMin = Vector2.zero;
        Panel.anchorMax = Vector2.one;
 
        //适配四个方向
        // Panel.offsetMin = safeArea.min;
        // Panel.offsetMax = new Vector2(-(Screen.width - safeArea.max.x), -(Screen.height - safeArea.max.y));
 
        //只适配两边
        Panel.offsetMin = new Vector2(safeArea.min.x, 0);
        Panel.offsetMax = new Vector2(-(Screen.width - safeArea.max.x), 0);
 
        LastRect = Panel.rect;
        LastSafeArea = safeArea;
    }
    #endregion 
}