<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<!-- 設置在蘋果手機上以應用模式啟動時,是否全屏 -->
<meta name='apple-touch-fullscreen' content='yes'>
<!-- ios 系統 作用未知 -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- iso 系統 作用未知 -->
<meta content="fullscreen=yes,preventMove=no" name="ML-Config">
<!-- iso 系統 作用未知 -->
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- 是否識別 手機號碼、 電子郵件 地址 等-->
<meta name="format-detection" content="telephone=no,email=no,address=no" />
<!-- 讓360雙核瀏覽器用webkit內核渲染頁面 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
允許全屏模式瀏覽,隱藏瀏覽器導航欄--><meta name="apple-mobile-web-app-capable" content="yes" />
<!--微信緩存--> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" />
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<!-- 讓360雙核瀏覽器用webkit內核渲染頁面 --> <meta name="renderer" content="webkit"> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script><![endif]-->
body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, time, mark, audio, video { margin:0;padding:0;border: 0;}
ol,li,ul,dl,dt,dd{list-style:none;}
table{border-collapse:collapse;border-spacing:0}
h1,h2,h3,h4,h5,h6,i,strong {font-weight: normal;}
img {vertical-align: middle;border: none;width: 100%;} i {font: inherit;}
a {color: #fff;text-decoration: none;-webkit-tap-highlight-color: rgba(0, 0, 0, 0); background-color:transparent;}
a:hover {text-decoration: underline; outline: none;}
select::-ms-expand { display: none; }
a:active,a:hover{outline:0}
.clearfix::before,.clearfix::after{ content: ''; display: block; height: 0; line-height: 0; visibility: hidden; clear: both;
}
.fl{ float:left;}.fr{float:right;}
input,select,option{vertical-align:middle;border-radius:0px;-moz-appearance:none;-webkit-appearance:none;appearance:none;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;}
input[type="text"],input[type="button"],input[type="submit"],input[type="reset"]{-webkit-appearance: none;appearance: none;border-radius: 0;outline: none;}
.overflow {overflow:hidden; }
body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, time, mark, audio, video { margin:0;padding:0}
ol,li,ul,dl,dt,dd{list-style:none;}.fl {float: left;} .fr {float: right;}
table{border-collapse:collapse;border-spacing:0}
html {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
/* 解決IOS默認滑動很卡的情況 */
-webkit-overflow-scrolling : touch;
}
/* 禁止縮放表單 */
input[type="submit"], input[type="reset"], input[type="button"], input {
resize: none;
border: none;
}
/* 取消鏈接高亮 */
body, div, ul, li, ol, h1, h2, h3, h4, h5, h6, input, textarea, select, p, dl, dt, dd, a, img, button, form, table, th, tr, td, tbody, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
/* 設置HTML5元素為塊 */
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
display: block;
}
/* 圖片自適應 */
img {
width: 100%;
height: auto;
width: auto\9; /* ie8 */
-ms-interpolation-mode: bicubic;/*為了照顧ie圖片縮放失真*/
}
em, i {
font-style: normal;
}
textarea {
resize:none; /*禁用了文本的拖拉,尤其在谷歌下*/
}
p {
word-wrap:break-word; /* 不夠的單詞自動換行 而不會被截掉 */
}
.clearfix:after {
content: "";
display: block;
visibility: hidden;
height: 0;
clear: both;
}
.clearfix {
zoom: 1;
}
a {
text-decoration: none;
color: #fff;
font-family: 'Microsoft YaHei', Tahoma, Arial, sans-serif;
}
a:hover {
text-decoration: none; outline: none;
}
h1, h2, h3, h4, h5, h6 {
font-size: 100%;
font-family: 'Microsoft YaHei';
}
img {
border: none;
}
input{
font-family: 'Microsoft YaHei';
}
/*單行溢出*/
.one-txt-cut{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
/*多行溢出 手機端使用*/
.txt-cut{
overflow : hidden;
text-overflow: ellipsis;
display: -webkit-box;
/* -webkit-line-clamp: 2; */
-webkit-box-orient: vertical;
}
/* 移動端點擊a鏈接出現藍色背景問題解決 */
a:link,a:active,a:visited,a:hover {
background: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-tap-highlight-color: transparent;
}
.overflow {overflow:hidden; }
.w50{
width: 50%;
}
.w25{
width: 25%;
}
.w20{
width: 20%;
}
.w33{
width: 33.333333%;
}
html設置初始font-size:320px的字體大小
var html = document.getElementsByTagName('html')[0];
if (html) {
var w = window.innerWidth;
var fontSize = (w > 640 ? 640 : w) / 640 * 30;
html.style.fontSize = fontSize + 'px';
}
window.onload = function () {
window.onresize = function () {
var w = window.innerWidth;
console.log(w);
var fontSize = (w > 640 ? 640 : w) / 640 * 30;
html.style.fontSize = fontSize + 'px';
}
}
html設置初始font-size:320px的字體大小
(function (doc, win) {
var docEl = doc.documentElement;
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
var recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
docEl.style.fontSize = (clientWidth > 640 ? 640 : clientWidth) / 320 * 20 + 'px';
}; // 不同瀏覽器resize事件處理機制不同 // 使用定時器延遲處理resize回調函數以降低重復響應
var recalcTimer = null;
var delaycalc = function () {
win.clearTimeout(recalcTimer);
recalcTimer = win.setTimeout(recalc, 100);
}; // 移動端不需要考慮事件注冊函數的兼容性
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, delaycalc, false); // DOMContentLoaded事件只在DOM文檔樹加載完畢觸發,此處不用延遲處理
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
html {
font-size: 15px
}
html {
font-size: 4.7vw;
/* rem(root element)配合vw(viewport width) */
}
@media only screen and (min-width:320PX) and (max-width:359PX) {
html {
font-size: 15px
}
}
@media only screen and (min-width:360PX) and (max-width:374PX) {
html {
font-size: 16.875px
}
}
@media only screen and (min-width:375PX) and (max-width:389PX) {
html {
font-size: 17.5781px
}
}
@media only screen and (min-width:390PX) and (max-width:400PX) {
html {
font-size: 18.75px
}
}
@media only screen and (min-width:401PX) and (max-width:414PX) {
html {
font-size: 19.4063px
}
}
@media only screen and (min-width:415PX) and (max-width:640PX) {
html {
font-size: 22.5px
}
}
@media screen and (min-width:641PX) {
html {
font-size: 30px
}
}
html {
font-size: 4.2vw;
/* rem(root element)配合vw(viewport width) */
}
html {
font-size: 13.65px
}
@media only screen and (min-width:320PX) and (max-width:360PX) {
html {
font-size: 13.65px
}
}
@media only screen and (min-width:360PX) and (max-width:375PX) {
html {
font-size: 15.36px
}
}
@media only screen and (min-width:375PX) and (max-width:390PX) {
html {
font-size: 16px
}
}
@media only screen and (min-width:390PX) and (max-width:414PX) {
html {
font-size: 16.64px
}
}
@media only screen and (min-width:414PX) and (max-width:460PX) {
html {
font-size: 17.664px
}
}
@media only screen and (min-width:460PX) and (max-width:640PX) {
html {
font-size: 20px
}
}
@media screen and (min-width:640PX) {
html {
font-size: 27.31px
}
}
新舊版本兼容:這里設置flex容器為.box,子元素為.item
.box {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
display: -webkit-box;
display: -moz-box;
}
舊版:display:box
新版:display:flex
水平方向:
.box {
-moz-flex-direction: row;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-box-direction: normal;
-webkit-box-orient: horizontal;
}
.box {
-moz-flex-direction: column;
-webkit-flex-direction: column;
flex-direction: column;
-webkit-box-direction: normal;
-webkit-box-orient: vertical;
}
舊版:box-direction: normal 水平方向 | reverse 垂直方向 | inherit ,跟子元素的方向一致; 定義子元素的顯示方向。
box-orient: horizontal 水平排列| vertical 垂直排列| inline-axis 默認 | block-axis 快方式排列 | inherit繼承父元素; 定義子元素是否應水平或垂直排列。
這兩種要同時設置才能確定排列方式;
水平方向:box-direction: normal;box-orient: horizontal
垂直方向:box-direction: normal; box-orient:vertical
新版:flex-direction:row(默認值):主軸為水平方向,起點在左端。
row-reverse:主軸為水平方向,起點在右端。
column:主軸為垂直方向,起點在上沿。
column-reverse:主軸為垂直方向,起點在下沿。
.box {
-moz-justify-content: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-pack: center;
}
舊版: box-pack: start | end | center | justify;
注意:兼容寫法新版語法的space-around是不可用的
新版:justify-content:flex-start(默認值):左對齊
flex-end:右對齊
center: 居中
space-between:兩端對齊,項目之間的間隔都相等。
space-around:每個項目兩側的間隔相等。所以,項目之間的間隔比項目與邊框的間隔大一倍。
.box {
-moz-align-items: center;
-webkit-align-items: center;
align-items: center;
-webkit-box-align: center;
}
舊版: box-align: start | end | center | baseline | stretch;
新版:align-items:flex-start:交叉軸的起點對齊。
flex-end:交叉軸的終點對齊。
center:交叉軸的中點對齊。
baseline: 項目的第一行文字的基線對齊。
stretch(默認值):如果項目未設置高度或設為auto,將占滿整個容器的高度。
.item{ -moz-flex: 1;
-webkit-flex: 1; flex: 1;
-webkit-box-flex: 1.0;}
舊版:box-flex:1.0浮點數字
新版:flex:1 數字
要求換行
.box{ flex-wrap:wrap; box-lines: multiple; }
舊版: box-lines: single默認不允許 | multiple 允許;
新版:flex-wrap: nowrap 不換行
wrap 換行,第一行在上方
wrap-reverse 換行,第一行在下方
01、行內元素也可以定義flex語法:不常用
.box{ display: -webkit-inline-flex; display: inline-flex;}:
02、父元素屬性align-content屬性 定義在多跟抽線的對齊方式,一般是換行以后的對齊方式,只有一條抽線改屬性不生效,常用在換行以后有間距的問題:設置align-content:flex-start; 不常用
align-content:flex-start:與交叉軸的起點對齊。 flex-end:與交叉軸的終點對齊。 center:與交叉軸的中點對齊。 space-between:與交叉軸兩端對齊,軸線之間的間隔平均分布。 space-around:每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍。
stretch(默認值):軸線占滿整個交叉軸。
03、子元素屬性flex,是flex-grow, flex-shrink 和 flex-basis的簡寫,一般只定義子元素占多少份,常用
04、子元素屬性flex-grow 定義子元素占一行的多少份,值為數字 不常用
05、子元素屬性flex-basis屬性 定義了在分配多余空間之前,項目占據的主軸空間 像素單位和百分比,默認auto
06、子元素屬性flex-shrink屬性 定義了子元素的縮小比例,如果所有項目的flex-shrink屬性都為1,當空間不足時,都將等比例縮小。如果一個項目的flex-shrink屬性為0,其他項目都為1,則空間不足時,前者不縮小。負值無效
07、 子元素屬性order屬性 定義子元素的排列方式,數值越小,越靠前排列,數字
08、子元素屬性align-self屬性 定義允許單個項目有與其他項目不一樣的對齊方式,會覆蓋algin-items屬性 不常用
align-self: auto 默認 表示繼承父元素
flex-start 與交叉軸的起點對齊。
flex-end 與交叉軸的終點對齊。
center 與交叉軸的中點對齊
baseline: 項目的第一行文字的基線對齊。
stretch(默認值):如果項目未設置高度或設為auto,將占滿整個容器的高度。
justify-content: space-around 不能用
flex-wrap: wrap 不能用
-webkit-前綴標準版-moz-前綴標準版標準版-webkit-前綴09版
示例:
.box {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
display: -webkit-box;
display: -moz-box;
}
定義flex:
.box {
display: -webkit-flex;
/*webkit*/
display: flex;
}
/*行內flex*/
.box {
display: -webkit-inline-flex;
/*webkit*/
display: inline-flex;
}
父元素屬性:
.box {
flex-direction: row | row-reverse | column | column-reverse;
/*主軸方向:左到右(默認) | 右到左 | 上到下 | 下到上*/
flex-wrap: nowrap | wrap | wrap-reverse;
/*換行:不換行(默認) | 換行 | 換行并第一行在下方*/
flex-flow: <flex-direction> || <flex-wrap>;
/*主軸方向和換行簡寫*/
justify-content: flex-start | flex-end | center | space-between | space-around;
/*主軸對齊方式: 左對齊(默認) | 右對齊 | 居中對齊 | 兩端對齊 | 平均分布*/
align-items: flex-start | flex-end | center | baseline | stretch;
/*交叉軸對齊方式:頂部對齊(默認) | 底部對齊 | 居中對齊 | 上下對齊并鋪滿 | 文本基線對齊*/
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
/*多主軸對齊:頂部對齊(默認) | 底部對齊 | 居中對齊 | 上下對齊并鋪滿 | 上下平均分布*/
}
子元素屬性:
.item {
order: <integer>;
number
/*排序:數值越小,越排前,默認為0*/
flex-grow: <number>;
/* default 0 */
/*放大:默認0(即如果有剩余空間也不放大,值為1則放大,2是1的雙倍大小,以此類推)*/
flex-shrink: <number>;
/* default 1 */
/*縮小:默認1(如果空間不足則會縮小,值為0不縮小)*/
flex-basis: <length> | auto;
/* default auto */
/*固定大小:默認為0,可以設置px值,也可以設置百分比大小*/
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'>]
/*flex-grow, flex-shrink 和 flex-basis的簡寫,默認值為0 1 auto,*/
align-self: auto | flex-start | flex-end | center | baseline | stretch;
/*單獨對齊方式:自動(默認) | 頂部對齊 | 底部對齊 | 居中對齊 | 上下對齊并鋪滿 | 文本基線對齊*/
}
原文鏈接:https://blog.csdn.net/xgb0610/article/details/80416024
數字化轉型的浪潮下,MISBoot低代碼開發平臺正成為越來越多企業的首選,其拖拉拽自定義表單功能更是成為業務人員的利器,實現了零代碼開發的理想。這項革新技術不僅讓業務人員輕松上手,還能直接掛載菜單應用,結合流程引擎、數據報表、電子簽章等功能,適配移動端,擁有40種組件并可自行擴展,每個組件都有獨立屬性設置,列表字段、查詢字段、列表配置都可以獨立配置,同時還具備添加顯隱規則、加載表單時觸發、提交表單前觸發、提交表單后觸發等js、css代碼的功能。這篇文章將深入探討低代碼開發平臺拖拉拽自定義表單功能的強大之處,以及它對企業數字化轉型的重要意義。
隨著數字化轉型的推進,企業對快速、靈活地開發應用程序和解決方案的需求日益增長。傳統的軟件開發過程往往耗時費力,需要專業的編程技能和繁瑣的代碼編寫,這給業務人員帶來了很大的挑戰。然而,低代碼開發平臺的崛起改變了這一局面。低代碼開發平臺為業務人員提供了一種全新的開發范式,使他們可以通過直觀的圖形界面和拖拉拽操作就能創建應用程序,無需編寫一行代碼。其中的拖拉拽自定義表單功能更是低代碼開發平臺的一大特色,讓業務人員可以輕松定制和調整表單布局,設定字段的驗證規則,配置列表顯示和查詢條件,實現了真正意義上的零代碼開發。
基于MISBoot低代碼開發平臺的拖拉拽自定義表單功能簡直是讓業務人員擁有了無限的可能性。這項功能使得業務人員能夠根據實際需求,輕松創建符合自身業務流程的數據輸入界面,無需編寫一行代碼。通過簡單的拖拉拽和配置,就能完成一個完整的數據輸入表單,包括40種組件可供選擇,并且每個組件都有獨立的屬性設置,滿足了各種不同的業務需求。同時,拖拉拽自定義表單功能適配移動端,使得用戶可以在手機端便捷地進行表單操作,大大提升了工作效率和靈活性。
拖拉拽自定義表單的靈活性和擴展性也是其獨特之處。每個組件都可以執行擴展,使得平臺可以適應各種復雜的業務場景。同時,列表字段、查詢字段、列表配置都可以獨立配置,為用戶提供了更多的個性化選擇,滿足了不同用戶的特定需求。此外,拖拉拽自定義表單還具備添加顯隱規則、表單時觸發、提交表單前觸發、提交表單后觸發等js、css代碼的功能,讓用戶可以根據實際需求進行更加靈活的定制和擴展,實現更多樣化的業務邏輯。
MISBoot低代碼開發平臺 - 基于Spring Cloud微服務架構的拖拉拽自定義表單功能正在成為企業數字化轉型的利器,它將業務人員從繁瑣的編程工作中解放出來,使他們能夠更專注于業務需求的實現和創新。隨著技術的不斷演進和平臺功能的不斷完善,相信拖拉拽自定義表單將在未來發揮越來越重要的作用,成為企業應用開發的標配工具之一。
MISBoot低代碼開發平臺 - 基于Spring Cloud微服務架構的拖拉拽自定義表單功能不僅實現了零代碼開發的夢想,更讓業務人員輕松上手,為企業數字化轉型注入了強大的活力和創造力。其靈活性、擴展性以及適配移動端的特點,將為企業帶來更高效的業務流程和更好的用戶體驗,助力企業持續創新與發展。隨著其不斷的演進和普及,必將成為企業信息化建設的重要推動力量,為企業贏得更多商業機會和競爭優勢。
表單分類使業務更清晰
在線設計管理
表單在線系統配置界面
表單數據配置界面
桌面端表單設計區,豐富的組件及屬性配置
移動端表單設計區,豐富的組件及屬性配置
豐富的桌面端、移動端列表字段、查詢字段、列表配置
多種表單預覽方式
直接掛載菜單,掛載直接使用
直接綁定數據報表功能
直接綁定數據報表功能在線打印等
表單預覽功能
toryboard是蘋果一直推薦使用的界面開發方式。在近幾年的 Xcode 更新中可以看出,蘋果對 Storyboard 的開發力度也不斷增強,添加了更多功能和特性,大大方便了界面的開發、適配以及提升代碼性能。
Storyboard 最大的好處就是把界面和代碼分離,如同 Web 開發中 CSS 描述界面,HTML 描述內容,JavaScript 描述行為一樣,能讓代碼變得更清晰易讀,界面的行為以及相互的邏輯也變得更直觀。這對團隊開發來說是大大的好事。
在我們準備著手開發 Catfan App 的時候,由于剛好 iOS 9 發布不久,而且 Swift 語言也逐漸穩定成熟,所以決定拋棄以往純手寫或 xib 來構建界面的歷時包袱,完全使用純 Storyboard 來進行開發。
在團隊開發中,由于每個成員對 Storyboard 都有不一樣的理解,這往往會導致在使用的時候出現各種沖突。這時候就需要要引入一套 Storyboard 的使用規范來避免。
目前使用純 Storyboard 開發的大型開源項目不多,我們主要參考了 WordPress、Wikipedia 以及 IBAnimateable 官方項目的用法,并且在實踐中不斷研究探索來進行調整。
Storyboard 分離規范
除非是單頁面應用,在大多數情況下,使用單一 Storyboard 往往是不可行的,因為每個 App 通常由各種不一樣的復雜模塊構成,每當里面的一個元素的屬性或位置產生變化,都會導致整個 Storyboard 文件產生多處代碼的變動。尤其在 Git 代碼版本的控制下,處理分支合并產生的沖突會變得非常麻煩。
所以,把 Storyboard 分離有一個 1 - 5 原則:把每一個 Storyboard 盡量分離成一個人處理范圍,每一個 Storyboard 盡量控制少于 5 個 View。例如,設置頁面、注冊頁面、信息詳情頁、發布頁面等,基本上只需要一人就能負責,而且頁面大多數情況下都會少于 5 個 View (如果超過 5 個的時候,就可以考慮是不是在里面可以考慮把它們再分離)。把該模塊的所有 View 都放在同一個的 Storyboard 文件里進行管理。這樣就能大大減少相互沖突的情況,并且 Storyboard 的讀取和渲染性能也比單獨打開一個大型 Storyboard 的要快不少。
Storyboard 命名規范
一套優秀的代碼項目,變量的命名,代碼的語言風格都會有一套對應的規范,以便于成員之間進行溝通和開發。在 Storyboard 里面,各種的元素標識同樣地也需要一套命名的規范,以便于開發之間的溝通。
盡管我們可以通過元素的 Identity Inspector 頁面中的 Label 屬性對元素進行強制命名標識。但 Xcode 有一個特性,當元素拖拉到代碼處進行 IBOutlet 的變量綁定時候,該元素的標識會自動根據變量的名字進行自動命名,無需在 Label 屬性中進行指定。其命名規則是把駝峰寫法的變量的每個單詞添加空格分隔,并且每個單詞的首字母大寫。例如:albumCollectionViewController -> Album Collection View Controller,passwordLabel -> Password Label。簡單來說,元素標識的命名等同于在代碼中的變量名稱。
所以,根據這個特性,我們只需要在代碼的元素變量命名中應用一套規范,就能同時規范在 Storyboard 中的命名了。
通常情況下,IBOutlet 變量使用【控件作用的名稱 + Xcode 控件默認名】來命名會有不少的好處。
例如:
album + CollectionView
username + Label
avatar + ImageView
content + TextView
規則簡單,可讀性強。
自動轉化成 Storyboard 的名稱,如 Album Collection View、 Username Label、 Avatar Image View 等等,都符合 Xcode 默認的命名規范,顯得一致。
在代碼中調用方法時,很容易就能識別出該變量在界面中是什么類型的元素,包含什么屬性和方法。(當輸入 avatarImageView. 的時候,你就能知道它會有 image 這個屬性了)
(點擊放大圖像)
Storyboard 界面規范
Storyboard 除了作為 UI 界面的構建語言之外,還擔當著界面預覽的角色。界面規范有一個原則,就是當把 Storyboard 展示給其他人的時候,盡量做到能讓別人一看就知道這個 Storyboard 是干什么的,界面之間的邏輯是怎樣的,界面大致的效果是如何的。
布局規范
Xcode 本身就有就有布局輔助線提示的功能,當進行拖動的時候,可以根據提示的輔助線來進行 View 或控件之間的對齊,合理利用此特性能方便我們調整出整齊的布局。
View 和 View 之間的擺放,可以遵循從左往右,從上到下的原則,進行邏輯排列。因為在 Storyboard 里 View 之間的連線算法都是從 View 的右邊緣出發,到另外一個 View 的左邊緣結束,如果調轉了,就會出現很多交叉的連線,讓界面看起來很亂。
其次,View 之間最好也留有足夠的間隔,不要太擠,也不需要太遠。大概在大于四分之一,小于四分之三 View Contrller 的寬度(默認是 600 * 600)較佳。
在 Xcode 7 里,新增加了 Storyboard Reference 控件(雖然是在 iOS 9 新增加的,但 iOS 8 也可用)。合理使用此控件,能讓 Storyboard 描述出 View 與其它 Storyboard 的跳轉邏輯。并且可以通過 Segue 來進行 View 之間的數據傳遞,統一規范 View 之間跳轉的代碼,讓邏輯更清晰。
但總的來說,布局的位置基本上因人而異,沒有完全正確的布局方式。只要在擺放的時候,花點時間思考如何讓人看起來舒服,有邏輯性,那基本上就能達到目的了。
(點擊放大圖像)
設置規范
為了達到在 Storyboard 里,能呈現出 View 在運行時大致的界面,在設置 View 與各種控件的時候,同樣需要制定一些規范,以達到統一的展示效果。
例如在設置 Label、Text View 等作為內容 Placeholder 的時候,text 屬性所填寫的最好是實際運行時所呈現內容的例子。如展示用戶名的 Lable 就填寫 Username,展示時間的 Label 就填寫 2010-01-01,展示內容的 Text View 就填寫一些 Lorem ipsum dolor sit ... 等默認內容之類的。如果不這樣區分,界面中一大堆默認的 Label 會是怎樣的一種感覺?
對于展示固定內容的 text 屬性,那最好都統一基于 Based Language 來設置,否則如果在后期需要對程序進行多國語言化的時候,會非常麻煩。
在新版的 Xcode 里,還新增加了 IBDesignable 和 IBInspectable 兩個特性,只需要添加一些代碼,就能讓 Storyboard 里的控件呈現出更加接近運行時所呈現的效果。有興趣的,可以參考相關的文章介紹。
全局開發規范
除了上述的規范外,還有更多細節的地方是會可能涉及到整個項目所有 Storyboard 的設置的。例如:
文字字體,字體大小,各元素的顏色
語言定義
Autolayout 設置方式
界面自適應設置
UITest 相關設置
更多
這些都需要在統一開發之前,預先進行團隊協商和定義。最好能把它寫成一個團隊文檔,讓所有成員都遵循這個方式進行設定,這樣就能減少開發中可能產生的沖突,透過 Storyboard 的方式,讓 iOS 開發變得更加便捷。
總結
盡管使用規范會因團隊、項目、技術等的不同要素而有所差異。但總的來說,在開發時訂立一套團隊Storyboard的使用規范,將會大大提升項目整體開發的質量以及速度。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。