Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
<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">
<!-- 設(shè)置在蘋果手機(jī)上以應(yīng)用模式啟動(dòng)時(shí),是否全屏 -->
<meta name='apple-touch-fullscreen' content='yes'>
<!-- ios 系統(tǒng) 作用未知 -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- iso 系統(tǒng) 作用未知 -->
<meta content="fullscreen=yes,preventMove=no" name="ML-Config">
<!-- iso 系統(tǒng) 作用未知 -->
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- 是否識(shí)別 手機(jī)號(hào)碼、 電子郵件 地址 等-->
<meta name="format-detection" content="telephone=no,email=no,address=no" />
<!-- 讓360雙核瀏覽器用webkit內(nèi)核渲染頁面 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
允許全屏模式瀏覽,隱藏瀏覽器導(dǎo)航欄--><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內(nèi)核渲染頁面 --> <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默認(rèn)滑動(dòng)很卡的情況 */
-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);
}
/* 設(shè)置HTML5元素為塊 */
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
display: block;
}
/* 圖片自適應(yīng) */
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; /* 不夠的單詞自動(dòng)換行 而不會(huì)被截掉 */
}
.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;
}
/*多行溢出 手機(jī)端使用*/
.txt-cut{
overflow : hidden;
text-overflow: ellipsis;
display: -webkit-box;
/* -webkit-line-clamp: 2; */
-webkit-box-orient: vertical;
}
/* 移動(dòng)端點(diǎn)擊a鏈接出現(xiàn)藍(lán)色背景問題解決 */
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設(shè)置初始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設(shè)置初始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事件處理機(jī)制不同 // 使用定時(shí)器延遲處理resize回調(diào)函數(shù)以降低重復(fù)響應(yīng)
var recalcTimer = null;
var delaycalc = function () {
win.clearTimeout(recalcTimer);
recalcTimer = win.setTimeout(recalc, 100);
}; // 移動(dòng)端不需要考慮事件注冊(cè)函數(shù)的兼容性
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, delaycalc, false); // DOMContentLoaded事件只在DOM文檔樹加載完畢觸發(fā),此處不用延遲處理
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
}
}
新舊版本兼容:這里設(shè)置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 默認(rèn) | block-axis 快方式排列 | inherit繼承父元素; 定義子元素是否應(yīng)水平或垂直排列。
這兩種要同時(shí)設(shè)置才能確定排列方式;
水平方向:box-direction: normal;box-orient: horizontal
垂直方向:box-direction: normal; box-orient:vertical
新版:flex-direction:row(默認(rèn)值):主軸為水平方向,起點(diǎn)在左端。
row-reverse:主軸為水平方向,起點(diǎn)在右端。
column:主軸為垂直方向,起點(diǎn)在上沿。
column-reverse:主軸為垂直方向,起點(diǎn)在下沿。
.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(默認(rèn)值):左對(duì)齊
flex-end:右對(duì)齊
center: 居中
space-between:兩端對(duì)齊,項(xiàng)目之間的間隔都相等。
space-around:每個(gè)項(xiàng)目兩側(cè)的間隔相等。所以,項(xiàng)目之間的間隔比項(xiàng)目與邊框的間隔大一倍。
.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:交叉軸的起點(diǎn)對(duì)齊。
flex-end:交叉軸的終點(diǎn)對(duì)齊。
center:交叉軸的中點(diǎn)對(duì)齊。
baseline: 項(xiàng)目的第一行文字的基線對(duì)齊。
stretch(默認(rèn)值):如果項(xiàng)目未設(shè)置高度或設(shè)為auto,將占滿整個(gè)容器的高度。
.item{ -moz-flex: 1;
-webkit-flex: 1; flex: 1;
-webkit-box-flex: 1.0;}
舊版:box-flex:1.0浮點(diǎn)數(shù)字
新版:flex:1 數(shù)字
要求換行
.box{ flex-wrap:wrap; box-lines: multiple; }
舊版: box-lines: single默認(rèn)不允許 | multiple 允許;
新版:flex-wrap: nowrap 不換行
wrap 換行,第一行在上方
wrap-reverse 換行,第一行在下方
01、行內(nèi)元素也可以定義flex語法:不常用
.box{ display: -webkit-inline-flex; display: inline-flex;}:
02、父元素屬性align-content屬性 定義在多跟抽線的對(duì)齊方式,一般是換行以后的對(duì)齊方式,只有一條抽線改屬性不生效,常用在換行以后有間距的問題:設(shè)置align-content:flex-start; 不常用
align-content:flex-start:與交叉軸的起點(diǎn)對(duì)齊。 flex-end:與交叉軸的終點(diǎn)對(duì)齊。 center:與交叉軸的中點(diǎn)對(duì)齊。 space-between:與交叉軸兩端對(duì)齊,軸線之間的間隔平均分布。 space-around:每根軸線兩側(cè)的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍。
stretch(默認(rèn)值):軸線占滿整個(gè)交叉軸。
03、子元素屬性flex,是flex-grow, flex-shrink 和 flex-basis的簡寫,一般只定義子元素占多少份,常用
04、子元素屬性flex-grow 定義子元素占一行的多少份,值為數(shù)字 不常用
05、子元素屬性flex-basis屬性 定義了在分配多余空間之前,項(xiàng)目占據(jù)的主軸空間 像素單位和百分比,默認(rèn)auto
06、子元素屬性flex-shrink屬性 定義了子元素的縮小比例,如果所有項(xiàng)目的flex-shrink屬性都為1,當(dāng)空間不足時(shí),都將等比例縮小。如果一個(gè)項(xiàng)目的flex-shrink屬性為0,其他項(xiàng)目都為1,則空間不足時(shí),前者不縮小。負(fù)值無效
07、 子元素屬性order屬性 定義子元素的排列方式,數(shù)值越小,越靠前排列,數(shù)字
08、子元素屬性align-self屬性 定義允許單個(gè)項(xiàng)目有與其他項(xiàng)目不一樣的對(duì)齊方式,會(huì)覆蓋algin-items屬性 不常用
align-self: auto 默認(rèn) 表示繼承父元素
flex-start 與交叉軸的起點(diǎn)對(duì)齊。
flex-end 與交叉軸的終點(diǎn)對(duì)齊。
center 與交叉軸的中點(diǎn)對(duì)齊
baseline: 項(xiàng)目的第一行文字的基線對(duì)齊。
stretch(默認(rèn)值):如果項(xiàng)目未設(shè)置高度或設(shè)為auto,將占滿整個(gè)容器的高度。
justify-content: space-around 不能用
flex-wrap: wrap 不能用
-webkit-前綴標(biāo)準(zhǔn)版-moz-前綴標(biāo)準(zhǔn)版標(biāo)準(zhǔn)版-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;
}
/*行內(nèi)flex*/
.box {
display: -webkit-inline-flex;
/*webkit*/
display: inline-flex;
}
父元素屬性:
.box {
flex-direction: row | row-reverse | column | column-reverse;
/*主軸方向:左到右(默認(rèn)) | 右到左 | 上到下 | 下到上*/
flex-wrap: nowrap | wrap | wrap-reverse;
/*換行:不換行(默認(rèn)) | 換行 | 換行并第一行在下方*/
flex-flow: <flex-direction> || <flex-wrap>;
/*主軸方向和換行簡寫*/
justify-content: flex-start | flex-end | center | space-between | space-around;
/*主軸對(duì)齊方式: 左對(duì)齊(默認(rèn)) | 右對(duì)齊 | 居中對(duì)齊 | 兩端對(duì)齊 | 平均分布*/
align-items: flex-start | flex-end | center | baseline | stretch;
/*交叉軸對(duì)齊方式:頂部對(duì)齊(默認(rèn)) | 底部對(duì)齊 | 居中對(duì)齊 | 上下對(duì)齊并鋪滿 | 文本基線對(duì)齊*/
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
/*多主軸對(duì)齊:頂部對(duì)齊(默認(rèn)) | 底部對(duì)齊 | 居中對(duì)齊 | 上下對(duì)齊并鋪滿 | 上下平均分布*/
}
子元素屬性:
.item {
order: <integer>;
number
/*排序:數(shù)值越小,越排前,默認(rèn)為0*/
flex-grow: <number>;
/* default 0 */
/*放大:默認(rèn)0(即如果有剩余空間也不放大,值為1則放大,2是1的雙倍大小,以此類推)*/
flex-shrink: <number>;
/* default 1 */
/*縮小:默認(rèn)1(如果空間不足則會(huì)縮小,值為0不縮小)*/
flex-basis: <length> | auto;
/* default auto */
/*固定大小:默認(rèn)為0,可以設(shè)置px值,也可以設(shè)置百分比大小*/
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'>]
/*flex-grow, flex-shrink 和 flex-basis的簡寫,默認(rèn)值為0 1 auto,*/
align-self: auto | flex-start | flex-end | center | baseline | stretch;
/*單獨(dú)對(duì)齊方式:自動(dòng)(默認(rèn)) | 頂部對(duì)齊 | 底部對(duì)齊 | 居中對(duì)齊 | 上下對(duì)齊并鋪滿 | 文本基線對(duì)齊*/
}
原文鏈接:https://blog.csdn.net/xgb0610/article/details/80416024
數(shù)字化轉(zhuǎn)型的浪潮下,MISBoot低代碼開發(fā)平臺(tái)正成為越來越多企業(yè)的首選,其拖拉拽自定義表單功能更是成為業(yè)務(wù)人員的利器,實(shí)現(xiàn)了零代碼開發(fā)的理想。這項(xiàng)革新技術(shù)不僅讓業(yè)務(wù)人員輕松上手,還能直接掛載菜單應(yīng)用,結(jié)合流程引擎、數(shù)據(jù)報(bào)表、電子簽章等功能,適配移動(dòng)端,擁有40種組件并可自行擴(kuò)展,每個(gè)組件都有獨(dú)立屬性設(shè)置,列表字段、查詢字段、列表配置都可以獨(dú)立配置,同時(shí)還具備添加顯隱規(guī)則、加載表單時(shí)觸發(fā)、提交表單前觸發(fā)、提交表單后觸發(fā)等js、css代碼的功能。這篇文章將深入探討低代碼開發(fā)平臺(tái)拖拉拽自定義表單功能的強(qiáng)大之處,以及它對(duì)企業(yè)數(shù)字化轉(zhuǎn)型的重要意義。
隨著數(shù)字化轉(zhuǎn)型的推進(jìn),企業(yè)對(duì)快速、靈活地開發(fā)應(yīng)用程序和解決方案的需求日益增長。傳統(tǒng)的軟件開發(fā)過程往往耗時(shí)費(fèi)力,需要專業(yè)的編程技能和繁瑣的代碼編寫,這給業(yè)務(wù)人員帶來了很大的挑戰(zhàn)。然而,低代碼開發(fā)平臺(tái)的崛起改變了這一局面。低代碼開發(fā)平臺(tái)為業(yè)務(wù)人員提供了一種全新的開發(fā)范式,使他們可以通過直觀的圖形界面和拖拉拽操作就能創(chuàng)建應(yīng)用程序,無需編寫一行代碼。其中的拖拉拽自定義表單功能更是低代碼開發(fā)平臺(tái)的一大特色,讓業(yè)務(wù)人員可以輕松定制和調(diào)整表單布局,設(shè)定字段的驗(yàn)證規(guī)則,配置列表顯示和查詢條件,實(shí)現(xiàn)了真正意義上的零代碼開發(fā)。
基于MISBoot低代碼開發(fā)平臺(tái)的拖拉拽自定義表單功能簡直是讓業(yè)務(wù)人員擁有了無限的可能性。這項(xiàng)功能使得業(yè)務(wù)人員能夠根據(jù)實(shí)際需求,輕松創(chuàng)建符合自身業(yè)務(wù)流程的數(shù)據(jù)輸入界面,無需編寫一行代碼。通過簡單的拖拉拽和配置,就能完成一個(gè)完整的數(shù)據(jù)輸入表單,包括40種組件可供選擇,并且每個(gè)組件都有獨(dú)立的屬性設(shè)置,滿足了各種不同的業(yè)務(wù)需求。同時(shí),拖拉拽自定義表單功能適配移動(dòng)端,使得用戶可以在手機(jī)端便捷地進(jìn)行表單操作,大大提升了工作效率和靈活性。
拖拉拽自定義表單的靈活性和擴(kuò)展性也是其獨(dú)特之處。每個(gè)組件都可以執(zhí)行擴(kuò)展,使得平臺(tái)可以適應(yīng)各種復(fù)雜的業(yè)務(wù)場(chǎng)景。同時(shí),列表字段、查詢字段、列表配置都可以獨(dú)立配置,為用戶提供了更多的個(gè)性化選擇,滿足了不同用戶的特定需求。此外,拖拉拽自定義表單還具備添加顯隱規(guī)則、表單時(shí)觸發(fā)、提交表單前觸發(fā)、提交表單后觸發(fā)等js、css代碼的功能,讓用戶可以根據(jù)實(shí)際需求進(jìn)行更加靈活的定制和擴(kuò)展,實(shí)現(xiàn)更多樣化的業(yè)務(wù)邏輯。
MISBoot低代碼開發(fā)平臺(tái) - 基于Spring Cloud微服務(wù)架構(gòu)的拖拉拽自定義表單功能正在成為企業(yè)數(shù)字化轉(zhuǎn)型的利器,它將業(yè)務(wù)人員從繁瑣的編程工作中解放出來,使他們能夠更專注于業(yè)務(wù)需求的實(shí)現(xiàn)和創(chuàng)新。隨著技術(shù)的不斷演進(jìn)和平臺(tái)功能的不斷完善,相信拖拉拽自定義表單將在未來發(fā)揮越來越重要的作用,成為企業(yè)應(yīng)用開發(fā)的標(biāo)配工具之一。
MISBoot低代碼開發(fā)平臺(tái) - 基于Spring Cloud微服務(wù)架構(gòu)的拖拉拽自定義表單功能不僅實(shí)現(xiàn)了零代碼開發(fā)的夢(mèng)想,更讓業(yè)務(wù)人員輕松上手,為企業(yè)數(shù)字化轉(zhuǎn)型注入了強(qiáng)大的活力和創(chuàng)造力。其靈活性、擴(kuò)展性以及適配移動(dòng)端的特點(diǎn),將為企業(yè)帶來更高效的業(yè)務(wù)流程和更好的用戶體驗(yàn),助力企業(yè)持續(xù)創(chuàng)新與發(fā)展。隨著其不斷的演進(jìn)和普及,必將成為企業(yè)信息化建設(shè)的重要推動(dòng)力量,為企業(yè)贏得更多商業(yè)機(jī)會(huì)和競(jìng)爭(zhēng)優(yōu)勢(shì)。
表單分類使業(yè)務(wù)更清晰
在線設(shè)計(jì)管理
表單在線系統(tǒng)配置界面
表單數(shù)據(jù)配置界面
桌面端表單設(shè)計(jì)區(qū),豐富的組件及屬性配置
移動(dòng)端表單設(shè)計(jì)區(qū),豐富的組件及屬性配置
豐富的桌面端、移動(dòng)端列表字段、查詢字段、列表配置
多種表單預(yù)覽方式
直接掛載菜單,掛載直接使用
直接綁定數(shù)據(jù)報(bào)表功能
直接綁定數(shù)據(jù)報(bào)表功能在線打印等
表單預(yù)覽功能
toryboard是蘋果一直推薦使用的界面開發(fā)方式。在近幾年的 Xcode 更新中可以看出,蘋果對(duì) Storyboard 的開發(fā)力度也不斷增強(qiáng),添加了更多功能和特性,大大方便了界面的開發(fā)、適配以及提升代碼性能。
Storyboard 最大的好處就是把界面和代碼分離,如同 Web 開發(fā)中 CSS 描述界面,HTML 描述內(nèi)容,JavaScript 描述行為一樣,能讓代碼變得更清晰易讀,界面的行為以及相互的邏輯也變得更直觀。這對(duì)團(tuán)隊(duì)開發(fā)來說是大大的好事。
在我們準(zhǔn)備著手開發(fā) Catfan App 的時(shí)候,由于剛好 iOS 9 發(fā)布不久,而且 Swift 語言也逐漸穩(wěn)定成熟,所以決定拋棄以往純手寫或 xib 來構(gòu)建界面的歷時(shí)包袱,完全使用純 Storyboard 來進(jìn)行開發(fā)。
在團(tuán)隊(duì)開發(fā)中,由于每個(gè)成員對(duì) Storyboard 都有不一樣的理解,這往往會(huì)導(dǎo)致在使用的時(shí)候出現(xiàn)各種沖突。這時(shí)候就需要要引入一套 Storyboard 的使用規(guī)范來避免。
目前使用純 Storyboard 開發(fā)的大型開源項(xiàng)目不多,我們主要參考了 WordPress、Wikipedia 以及 IBAnimateable 官方項(xiàng)目的用法,并且在實(shí)踐中不斷研究探索來進(jìn)行調(diào)整。
Storyboard 分離規(guī)范
除非是單頁面應(yīng)用,在大多數(shù)情況下,使用單一 Storyboard 往往是不可行的,因?yàn)槊總€(gè) App 通常由各種不一樣的復(fù)雜模塊構(gòu)成,每當(dāng)里面的一個(gè)元素的屬性或位置產(chǎn)生變化,都會(huì)導(dǎo)致整個(gè) Storyboard 文件產(chǎn)生多處代碼的變動(dòng)。尤其在 Git 代碼版本的控制下,處理分支合并產(chǎn)生的沖突會(huì)變得非常麻煩。
所以,把 Storyboard 分離有一個(gè) 1 - 5 原則:把每一個(gè) Storyboard 盡量分離成一個(gè)人處理范圍,每一個(gè) Storyboard 盡量控制少于 5 個(gè) View。例如,設(shè)置頁面、注冊(cè)頁面、信息詳情頁、發(fā)布頁面等,基本上只需要一人就能負(fù)責(zé),而且頁面大多數(shù)情況下都會(huì)少于 5 個(gè) View (如果超過 5 個(gè)的時(shí)候,就可以考慮是不是在里面可以考慮把它們?cè)俜蛛x)。把該模塊的所有 View 都放在同一個(gè)的 Storyboard 文件里進(jìn)行管理。這樣就能大大減少相互沖突的情況,并且 Storyboard 的讀取和渲染性能也比單獨(dú)打開一個(gè)大型 Storyboard 的要快不少。
Storyboard 命名規(guī)范
一套優(yōu)秀的代碼項(xiàng)目,變量的命名,代碼的語言風(fēng)格都會(huì)有一套對(duì)應(yīng)的規(guī)范,以便于成員之間進(jìn)行溝通和開發(fā)。在 Storyboard 里面,各種的元素標(biāo)識(shí)同樣地也需要一套命名的規(guī)范,以便于開發(fā)之間的溝通。
盡管我們可以通過元素的 Identity Inspector 頁面中的 Label 屬性對(duì)元素進(jìn)行強(qiáng)制命名標(biāo)識(shí)。但 Xcode 有一個(gè)特性,當(dāng)元素拖拉到代碼處進(jìn)行 IBOutlet 的變量綁定時(shí)候,該元素的標(biāo)識(shí)會(huì)自動(dòng)根據(jù)變量的名字進(jìn)行自動(dòng)命名,無需在 Label 屬性中進(jìn)行指定。其命名規(guī)則是把駝峰寫法的變量的每個(gè)單詞添加空格分隔,并且每個(gè)單詞的首字母大寫。例如:albumCollectionViewController -> Album Collection View Controller,passwordLabel -> Password Label。簡單來說,元素標(biāo)識(shí)的命名等同于在代碼中的變量名稱。
所以,根據(jù)這個(gè)特性,我們只需要在代碼的元素變量命名中應(yīng)用一套規(guī)范,就能同時(shí)規(guī)范在 Storyboard 中的命名了。
通常情況下,IBOutlet 變量使用【控件作用的名稱 + Xcode 控件默認(rèn)名】來命名會(huì)有不少的好處。
例如:
album + CollectionView
username + Label
avatar + ImageView
content + TextView
規(guī)則簡單,可讀性強(qiáng)。
自動(dòng)轉(zhuǎn)化成 Storyboard 的名稱,如 Album Collection View、 Username Label、 Avatar Image View 等等,都符合 Xcode 默認(rèn)的命名規(guī)范,顯得一致。
在代碼中調(diào)用方法時(shí),很容易就能識(shí)別出該變量在界面中是什么類型的元素,包含什么屬性和方法。(當(dāng)輸入 avatarImageView. 的時(shí)候,你就能知道它會(huì)有 image 這個(gè)屬性了)
(點(diǎn)擊放大圖像)
Storyboard 界面規(guī)范
Storyboard 除了作為 UI 界面的構(gòu)建語言之外,還擔(dān)當(dāng)著界面預(yù)覽的角色。界面規(guī)范有一個(gè)原則,就是當(dāng)把 Storyboard 展示給其他人的時(shí)候,盡量做到能讓別人一看就知道這個(gè) Storyboard 是干什么的,界面之間的邏輯是怎樣的,界面大致的效果是如何的。
布局規(guī)范
Xcode 本身就有就有布局輔助線提示的功能,當(dāng)進(jìn)行拖動(dòng)的時(shí)候,可以根據(jù)提示的輔助線來進(jìn)行 View 或控件之間的對(duì)齊,合理利用此特性能方便我們調(diào)整出整齊的布局。
View 和 View 之間的擺放,可以遵循從左往右,從上到下的原則,進(jìn)行邏輯排列。因?yàn)樵?Storyboard 里 View 之間的連線算法都是從 View 的右邊緣出發(fā),到另外一個(gè) View 的左邊緣結(jié)束,如果調(diào)轉(zhuǎn)了,就會(huì)出現(xiàn)很多交叉的連線,讓界面看起來很亂。
其次,View 之間最好也留有足夠的間隔,不要太擠,也不需要太遠(yuǎn)。大概在大于四分之一,小于四分之三 View Contrller 的寬度(默認(rèn)是 600 * 600)較佳。
在 Xcode 7 里,新增加了 Storyboard Reference 控件(雖然是在 iOS 9 新增加的,但 iOS 8 也可用)。合理使用此控件,能讓 Storyboard 描述出 View 與其它 Storyboard 的跳轉(zhuǎn)邏輯。并且可以通過 Segue 來進(jìn)行 View 之間的數(shù)據(jù)傳遞,統(tǒng)一規(guī)范 View 之間跳轉(zhuǎn)的代碼,讓邏輯更清晰。
但總的來說,布局的位置基本上因人而異,沒有完全正確的布局方式。只要在擺放的時(shí)候,花點(diǎn)時(shí)間思考如何讓人看起來舒服,有邏輯性,那基本上就能達(dá)到目的了。
(點(diǎn)擊放大圖像)
設(shè)置規(guī)范
為了達(dá)到在 Storyboard 里,能呈現(xiàn)出 View 在運(yùn)行時(shí)大致的界面,在設(shè)置 View 與各種控件的時(shí)候,同樣需要制定一些規(guī)范,以達(dá)到統(tǒng)一的展示效果。
例如在設(shè)置 Label、Text View 等作為內(nèi)容 Placeholder 的時(shí)候,text 屬性所填寫的最好是實(shí)際運(yùn)行時(shí)所呈現(xiàn)內(nèi)容的例子。如展示用戶名的 Lable 就填寫 Username,展示時(shí)間的 Label 就填寫 2010-01-01,展示內(nèi)容的 Text View 就填寫一些 Lorem ipsum dolor sit ... 等默認(rèn)內(nèi)容之類的。如果不這樣區(qū)分,界面中一大堆默認(rèn)的 Label 會(huì)是怎樣的一種感覺?
對(duì)于展示固定內(nèi)容的 text 屬性,那最好都統(tǒng)一基于 Based Language 來設(shè)置,否則如果在后期需要對(duì)程序進(jìn)行多國語言化的時(shí)候,會(huì)非常麻煩。
在新版的 Xcode 里,還新增加了 IBDesignable 和 IBInspectable 兩個(gè)特性,只需要添加一些代碼,就能讓 Storyboard 里的控件呈現(xiàn)出更加接近運(yùn)行時(shí)所呈現(xiàn)的效果。有興趣的,可以參考相關(guān)的文章介紹。
全局開發(fā)規(guī)范
除了上述的規(guī)范外,還有更多細(xì)節(jié)的地方是會(huì)可能涉及到整個(gè)項(xiàng)目所有 Storyboard 的設(shè)置的。例如:
文字字體,字體大小,各元素的顏色
語言定義
Autolayout 設(shè)置方式
界面自適應(yīng)設(shè)置
UITest 相關(guān)設(shè)置
更多
這些都需要在統(tǒng)一開發(fā)之前,預(yù)先進(jìn)行團(tuán)隊(duì)協(xié)商和定義。最好能把它寫成一個(gè)團(tuán)隊(duì)文檔,讓所有成員都遵循這個(gè)方式進(jìn)行設(shè)定,這樣就能減少開發(fā)中可能產(chǎn)生的沖突,透過 Storyboard 的方式,讓 iOS 開發(fā)變得更加便捷。
總結(jié)
盡管使用規(guī)范會(huì)因團(tuán)隊(duì)、項(xiàng)目、技術(shù)等的不同要素而有所差異。但總的來說,在開發(fā)時(shí)訂立一套團(tuán)隊(duì)Storyboard的使用規(guī)范,將會(huì)大大提升項(xiàng)目整體開發(fā)的質(zhì)量以及速度。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。