百思不得姐第3天:登錄注冊界面搭建


一:登錄注冊的界面效果如圖

二:界面的搭建

1:登陸界面一般都是moda的模式:新建控制器,勾選xib,則系統會自動關聯類,並且自動連線關聯view(若是后創建的控制器的xib,則類名相同,關聯類,在fileOwer處連線view),而我們自己不用去設置控制器view的frame。或是freeform,只需要更改控制器view的尺寸,例如4.7寸,那么在別的機型上運行正常適配。2:一般背景比較好看的都為背景圖片。 3:控制狀態欄的樣式:1:[UIApplication sharedApplication].statusBarStyle; 設置全局狀態的導航欄,還需要配置plist ,設置view controller base 為 no(不推薦) 2:從ios7開始就可以在控制器內,設值狀態欄。- (UIStatusBarStyle)preferredStatusBarStyle

{    return UIStatusBarStyleLightContent;}

兩者設置其一,則另一個就不管用,不推薦使用第一種,默認顏色為黑色。2:隱藏狀態欄:- (BOOL)prefersStatusBarHidden 若是配置了pills,則用[UIApplication sharedApplication].statusBar hidden

2:登錄界面的UI分析:1:控制器或是view,要想到分層封裝思想(參照新浪微博cell的封裝),將控制器或是view切分成一個個模塊,分析每個模塊都由哪些控件組成,將零散的控件都封裝在一個統一的模塊內部(具體參照view的方法),再看封裝的每一個模塊的內部view是否還可以繼續封裝,然后再看封裝的view,是否項目中的其他地方也可以用到,若是可以,則想到繼承,將公共部分抽成父類,子類去繼承父類,不同的部分在子類中實現,1:父類可在.h中暴露方法,再在.m中實現該方法,則子類也繼承了父類的方法,當子類調用父類的方法的時候,就會調用父類的實現方法 (新浪微博參數模型的抽父類繼承)2:若是有多個子類繼承同一個父類的時候,在父類中父類要根據不同的子類來執行不同的方法,此時父類可提供一個標識的屬性方法供子類繼承重寫其get方法,此時在父類中就可以區別不同的子類了(百思的主界面繼承結構)3:若是父類提供了某個方法,父類也實現了該方法,則子類繼承該方法后,繼續重寫該方法,1:若是不保留父類行為,可以不調用super。 2:調用代碼寫在super之上,重寫setframe方法,重新設計參數傳入super方法 3:寫在super之下,則先是保留父類的行為,在設置子類的行為 2:如圖的登陸界面,則封裝成三個view,上部一個view,中間一個view,底部一個view,而對於底部的view,也可以封裝成兩個view,上部一個view,底部一個view,底部的view中的按鈕又可以繼續去封裝  3:當拷貝xib中已經設置好的約束控件后,只會拷貝寬高約束,其他約束不會拷貝。如圖:中間為lable,兩邊為uimageView

補充:1:新浪微博cell的封裝MVVM思想:1:封裝的背景view0直接添加到cell上,又將微博正文view1 與 底部工具條 view2,封裝起來添加到view0上,底部的工具條view2封裝為一個整體view2,微博正文的view1的層級機構為原創微博view3與轉發微博的view4,將頭像昵稱時間皇冠,微博內容,圖片等信息都封裝在原創微博的view3里,其中微博的圖片又封裝了一層view5,專門用來顯示圖片,被轉發微博的微博正文和圖片都添加到view4上。注意:不管有沒有顯示,先將盡可能顯示的控件全部都添加到封裝的view中,再根據數據模型model的字段值來判斷讓控件顯示還是隱藏,要考慮到cell的循環利用(顯示了,還要隱藏回來),避免因為cell的復用出現數據錯亂。2:MVVM思想:把cellFrame封裝為一個數據模型,在cellFrame數據模型的內部status數據模型作為cellFrame數據模型的屬性,根據status數據模型的字段值來設置給個控件的frame,cellFrame的好處:既可以為控件設置frame,又可以為控件設置屬性值。而每一個封裝的view都對應一個cellFrame模型,在控制器內部的數據源也是存放的cellFrame的數據模型。MVVM思想層次結構更加清晰,大量簡化了控制器的代碼便於維護 3:如何設置cell的高度:1:在cell中設置:在cell中提供類方法傳入每行row對應的數據模型,根據數據模型的字段值計算出總的cell的高度 2:在model中提供高度的屬性,在model中重寫get方法,根據model中的字段值計算總的cell的高度,為了優化,還可以設置內存緩存,當計算過cell的高度后讓其直接返回,不再執行計算高度的方法。(推薦第二種)

      2:view的封裝方法:無論是代碼還是xib都要想到模塊化分層封裝的思想。

1:instanceType方法提供類方法快速返回對象,1:內部調用alloc init ,alloc init內部調用[alloc  initWithFrame ]方法,[super  initWithFrame ]會調用setFrame方法,可以重寫setFrame方法來設置自身固定的frame,禁止外界更改,還可以重寫setFrame設置cell的上下左右的間距,分割線等,當外界設置frame的時候,又會調用setFrame方法,當setFrame方法調用完畢后,才會調用layoutSubview方法來設置frame 2:可以在[alloc  initWithFrame ]方法中設置自身封裝view的一些特定屬性,或是一次性代碼 2:懶加載子控件:(懶加載的作用:1:不用考慮代碼的創建順序 2:保證只初始化一次  3:懶加載可用weak 和 strong 都可以)在懶加載的方法中設置子控件的屬性,並將子控件添加到父控件上。

2:重寫layoutSubView方法設置子控件的frame:在此方法內設置子控件的frame較為准確嚴謹,不要忘記調用super,且此方法配合setNeedsLayout和layoutIfneed配合使用:前者是異步調用layoutSubView方法,而后者layoutIfneed是立即調用layoutSubView方法來更新約束。1:如何拿到控件:1:屬性,成員變量,枚舉tag值(1:直接取,2:或是遍歷父控件的子控件數組,通過tag值取出,tag值一般不要設為0,不安全,因為所有控件默認的tag值都為0 3:一般在設置tag值的時候通過self.subviews,count 也可以設置tag值),或是繼承父類直接從父類屬性獲取   2:將創建的控件放在一個屬性定義的大數組中,若是含有不同類的控件則兩兩放在大數組中,在layoutSubView里通過for循環從數組中取出子控件 3:遍歷父控件的子控件數組:1:self.subViews(UIView和scroll隱藏掉兩個滾動條后是最純潔的view,除了自己添加的不含有任何 子控件,所以可以直接遍歷父控件的子控件數組),需要index就采用int i 遍歷,不需要就可以采用for in快速遍歷,並在外部定義index,內部index++,來記錄索引值,也可以用enumer來遍歷可以得到索引值和遍歷的對象。在遍歷時,先要做條件過濾(1:continue 2:return過濾,不執行return下面的代碼,3:break,跳出循環,不再循環)找到后設置值,並停止遍歷 2:若是遍歷父控件的self.subViews子控件數組,有時候系統父控件沒有直接提供屬性使用,這時,可以打印子控件數組或是通過ViewUI來調 試查看所需要的子控件是什么,這樣就可以拿到子控件從字符串轉化為類,NSClassFromString()(新浪設置中間加號按鈕)3:利用runtime拿到系統控件私有的屬性來進行設置

3:為封裝view設計model接口與業務邏輯接口:設計model接口,重寫model的set方法,為封裝view的子控件賦值。業務邏輯的接口設計:1:把與外界無關的業務邏輯全部封裝在類的內部,類再提供接口供外界訪問,保證外界調用時最簡潔最方便的的 2:對於接口的設計:一般用屬性接口重寫通過重寫代替方法接口,是否就提供BOOL屬性接口,不同類型,就提供枚舉type接口,外界想訪問類內部的什么方法,變量就給外部提供屬性接口。

4:業務邏輯的監聽處理:1:查看子類有沒有系統代理方法,通知方法,或是繼承UIControl的可以addTarget都可以實現監聽,若是子類沒有還可以查看父類有沒有上述 的方法,在查看系統的API時,可以查看其其英文注釋該方法的使用說明,也可以按住option鍵點擊某個方法來查看使用說明 2:通過重寫監聽:在開發中遇到問題首先考慮重寫,重寫非常好用,繼承父類,通過重寫父類的方法也可以對父類行為進行攔截,覆蓋或是監聽父類的行為。但是不要忘記調用super, 否則父類的默認行為就不會響應。3:當監聽自身的屬性變化的時候,可以使用kvo實現監聽,當屬性變化的時候可以去實現某些方法

 5:監聽回調:1:層級較淺時,用協議代理(1:仿照tableView的代理方法設計協議代理 2:有時需要重寫setDelegate方法來,也就是成為代理之后才可以去做某些設置)block,兩者都可以,當兩個類需要相互回調時,可以給協議代 理或是block設置返回值,就可以實現兩個類相互回調 2:層級較深的時候:可以利用通知回調,傳值,其中通知可以在當前線程或是子線程中執行(只看post通知的時候在哪個線程里,注冊觀察者后,執行通知方 法就在哪個線程),其中注冊觀察者也可以用block方式注冊觀察者,並指定收到通知后的block任務在哪個線程中執行(也可實現一次性的通知,在 block中執行完任務后,就取消觀察者),如果采用block的方式注冊的觀察者,要以熟悉定義id類型返回值類接受block通知的返回值,以便在 dealloc中注銷觀察者。一般項目中的通知名都寫在配置常量的類里  

6:考慮繼承關系:若是封裝的該view在項目中其他的地方也可以用到,則考慮用繼承,將相同的部分抽成父類,讓子類去繼承,不同的部分在子類中實現,父類可以給子類提供方法供子類去重寫,實現父類和子類相互的關聯

7:問題分析:當系統提供的控件不能滿足我們的要求的時候,我們可以選擇自定義控件,自定義控件繼承系統的控件,1:重寫layoutSubView方法,1:在該方法內部直接拿到系統的控件去設置 2:如果不能直接拿到系統的子控件,在該方法內部遍歷系統控件的子控件數組,並打印或是通過viewUI來調試查看子控件,再通過NSClassFromString來進行設置 3:利用runtime拿到系統控件內部私有的成員變量去設置(更改文本框的占位文字顏色)2:通過繼承關系,自定義控件的子類重寫父類的方法,super的調用三種情況。通過重寫父類的方法可以實現對父類行為的監聽,覆蓋,修改  3:還可以為系統的類寫分類,在分類中提供方法

 

3:控制器中代碼的規范:1:先分析界面的UI,分析好界面的封裝結構,先要整理好邏輯,把邏輯理順了,再去下手去寫代碼 2:1:在控制器中實現+(void)load,做一些常用配置(例如配置MJExtension字典轉模型的配置),不管有沒有子類,該方法只執行一次,並且不用導入頭文件 就可以調用,也就是該類被加載進內存就會調用 +(void)initalize該方法可能會被調用多次,當類被初始的時候會被調用,當有子類的時候,會先調用父類的+(void)initalize方法,在調用子類的+(void)initalize方法(父類中重寫了+(void)initalize方法,子類繼承,沒有重寫),在該方法中可以初始化一些配 置的設置或是只需要一次性設置的(自定義導航控制器設置全局導航主題,或是數據庫建表)重寫控制器的init方法,可以在控制器創建初始化時傳遞參數或是 初始化時做一些固定的一次性設置,例如設置tableView的樣式可以在初始化的時候調用,當控制器初始化的時候會調用控制器的init方法。-(void)loadView方法,重寫此方法可以更改控制器的self.view  viewDidLoad方法view加載完畢后調用,viewWillAppear 或是viewWillDidAppear 這兩個方法會調用不止一次,只要是界面出現即將出現就會調用,pop,dissmiss都會調用,一般在viewDidAppear方法中打印控件 的信息,因為此時控件已經完全顯示出來,viewWillDisappear,viewDiddisappear頁面即將消失或是已經消失 的時候調用,dealloc控制器銷毀的時候調用,在此方法中可以移除通知或是在控制器銷毀的時候傳遞給其他控制器一些數據信息。2:我們一般在 viewDidLoad方法中采取封裝方法調用 1:當控制器中某個方法含有大量重復的代碼時要考慮抽方法封裝,將相同的代碼抽到方法的內部,不同的部分作為參數傳遞 2:若是代碼中涉及某些業務邏輯的處理或是項目中各個地方都可以用到,則也應考慮到封裝:1:分類封裝:1:當此段業務邏輯與系統某個類有關系時,要想到 給系統類寫分類,而且能寫分類盡量寫分類,因為分類會少創建類,減少內存 2:分類的接口設計:對象方法或是類方法,類方法較對象方法簡餐粗暴,但是當需要傳遞兩個參數的時候可以考慮利用對象方法,分類中的self指的就是傳遞 的參數 ,若是在分類中以屬性定義變量,則只會生成set和get的聲明,不會生成實現也不會生成帶下划線的成員變量,若是此時外界想要訪問分類某個變量則可以用static定義的全局變量 在get方法中返回就可以了 2:管理類Tool封裝:單例或是類方法,在類方法中要是想獲得單例一樣的成員變量,就用static定義全局變量,該成員變量也可以采用懶加載模式,只 讓其初始化一次,外界若是想訪問該成員變量,則該類可以提供接口get方法接口,供外界調用(get方法接口也可以用點語法去調用)3:考慮繼承:將相同 的部分抽到父類,不同的部分分別在子類中去實現,父類可在.h中暴露方法供子類去重寫(父類可提供標識屬性,供子類去重寫,以便於在父類中區分不同子 類),子類重寫父類的方法后,也就相當於間接修改了父類的屬性,父類中也就可以拿到子類修改的屬性。3:控制器或是view中每一行代碼的編寫,都要力求 使最簡潔的,要反復推敲,提煉,直到代碼是最簡潔不能再抽為止。1:像是hidden或是返回bool值的方法中一句代碼解決 或是利用三目運算簡化ifelse 2:賦值散三部,最上面定位nil,中間賦值,最后賦值 3:有兩個返回值時,只用一個if,分別返回,不用if else 4:當遍歷的時候,先做條件過濾(continue,braek,或是return條件過濾),找到賦值,並停止遍歷。 

三:登陸界面的知識總結

1:背景為圖片,所以拖一個UIImageView設為其背景圖片,在xib的左側界面可以設置注釋,方便查看:左側都可以:1:添加

注釋  2:可以設置相互間的層級關系 ,父子關系  3:可以設置約束,可以選中左側的某一項,向另一個拖線設置約束,若是想設置多個約束,按住shift鍵,選擇多個約束,點擊add添加約束就可以了  3:

1:左邊寫注釋,可以拖動成為某某子控件設置控件之間的層級關系,可以進行兩個view之間的拖線限制約束  2:中間可以拉線設置約束  3:下面可以設置約束,一般設置對齊方式也會很簡單的  4:右側,查看約束,雙擊約束,可以更改約束的比例值

2:頂部view的約束設置:

1:xib設置按鈕:要設置按鈕的高亮狀態,如果用system樣式,則不能顯示高亮狀態,所以必須設置按鈕的狀態為custom狀態,如果按鈕的狀態為system樣式,則有時該按鈕會被系統渲染為藍色,圖片按鈕若不設置按鈕的寬高,則默認按鈕的寬高為圖片的寬高。  2:設置如圖所示的圖片按鈕:用set image,和setbackgruondImage都可以,但是最好用set image,圖片不會變形,還會增加額外點擊區域。setbackgruondImage,按鈕有多大,圖片有多大,有時圖片會變形的,若使其不變形,就讓圖片的size等於按鈕的size。

3:設置中間大view的約束:

具體思路:1:設置背景view的約束,先設置中間view左邊右邊對齊,頂部間距,高約束,當子控件再父控件上時,設置這些約束,就從如圖處設置:設置具體約束值的時候也從如圖處設置(如圖所設置的就是距離設置約束控件距離最近的控件),不用拉線太麻煩。設置間距值等寬登高,對齊方式就從如下圖的地方去設置。拉線一般不設置具體約束值的時候如等寬等高的時候,可以按住shift鍵拉線設置多個約束值並點擊add。(中間view最后會去除高度的約束,最后讓中間view的高度等於所有子控件的高度)

2:輸入框的約束的設置:1:輸入框背景為UIImageView,UIImageView設置水平居中,頂部約束,可以設置其寬高等於背景圖片的寬高 2:分別拖入兩個文本輸入框,在最左側分別選上文本框和背景圖片,在最下角處設置兩個左對齊,頂部,右對齊,高度等高,此時來到如圖所示:登高處雙擊更改為0.5,也就是為背景框的一半高度。拖密碼的文本框,設置左對齊,底部對齊,右對齊(在右下角設置子控件與父控件對齊)並設置兩個文本框對齊。

3:登錄按鈕的約束設置:同時在左側選中文本框背景和登陸按鈕,來到右下角,設置左對齊,右對齊,頂部間距約束,不設置寬高,讓其寬高等於圖片的寬高(lable,imageView,btn都可以不設置寬高約束,讓其根據內容自動計算寬高值)。

4:設置忘記密碼的約束:同時在左側選中文本框背景和忘記密碼按鈕,設置右對齊,頂部間距,不設置寬高約束,讓其直接根據按鈕內容的大小自動計算寬高值。

5:設置中間view的高度等於內部子控件的高度:刪除之前設置的中間view的高度,同時設置忘記密碼的的底部和中間view的底部約束就可以了

6:底部view的約束:為了適配,底部view的約束,也先設置左側底部右側頂部的約束,底部的view可以封裝為快速登陸的view,三個按鈕的約束。

7:三個按鈕的約束:三個分享按鈕放在一個大view里,讓按鈕的高度決定view的高度,設置左邊按鈕左間距,上下間距,右間距都為0,設置高度,另外兩個按鈕同樣,每個按鈕間距都為0,在分別選中三個按鈕,等寬登高就可以了,就可以平分整個view。在設置三個按鈕的大view的左側頂部,右側,底部距離底部view的間距。最后再刪除底部view的上部間距就可以了。

8:注冊界面的設置:直接comand+c 復制 command+v粘貼,在左側將注冊拖到當前的視圖單獨存在,在刪除忘記密碼,設置登陸按鈕距離注冊界面的底部間距,以計算出注冊界面的高度。同時在左側選中注冊界面和登陸的界面,設置頂部對齊,登寬,設置左側對其,來到最右側再雙擊設置注冊view的左邊和登陸的右邊對齊。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM