Swift3微博項目筆記(第二部分)

發(fā)布模塊
##
 - 點擊發(fā)布按鈕场斑,modal彈出一個控制器提岔,有發(fā)布微博、選擇相冊照片眶诈、表情鍵盤功能
- 1.發(fā)布按鈕屬于單獨的模塊截汪,新建一個文件來管理旷坦,創(chuàng)建一個ComposeViewController蹬癌,繼承自UIViewController,由于界面是固定的闷堡,使用XIB描述
- 2.點擊發(fā)布按鈕時骚勘,創(chuàng)建ComposeViewController對象铐伴,并包裝為導(dǎo)航控制器,然后modal彈出
- 3.給導(dǎo)航欄添加【關(guān)閉】和【發(fā)布】按鈕俏讹,默認(rèn)情況下用戶沒有輸入文字時【發(fā)布】按鈕不能點擊‘
- 4.導(dǎo)航標(biāo)題上有兩個Label当宴,上面顯示【發(fā)微博】,下面顯示【開發(fā)者的昵稱】泽疆,由于導(dǎo)航的title只能顯示一個Label户矢,所以這里需要自定UIView來添加兩個按鈕
- 5.創(chuàng)建ComposeTitleView,繼承UIView殉疼,重寫initWithFrame梯浪,懶加載這兩個Lable,將這兩個控件添加到ComposeTitleView中瓢娜,這里不要設(shè)置Frame挂洛,因為這兩個Label還要有間距,如果直接設(shè)置Frame眠砾,下面一個控件的Y值就不好計算了虏劲,所以可以使用約束,導(dǎo)入SnapKit框架,接下來將控件的屬性也封裝在里面
- 6.在ComposeViewController中懶加載ComposeTitleView
##
- 7.使用TextView作為輸入框褒颈,但是TextView在沒有輸入文字時并沒有【占位文字】伙单,需要自定義TextView,往里面添加一個Label子控件作為占位文字
- 8.在XIB上添加TextView哈肖,設(shè)置約束距離控制器View上下左右為0
- 9.創(chuàng)建一個繼承自UITextView的類ComposeTextView吻育,然XIB上的TextView控件的Class成為ComposeTextView
- 10.在awakeFromNib或initWithCoder中初始化,當(dāng)一個控件從XIB中加載時淤井,會先執(zhí)行initWithCoder布疼,再執(zhí)行awakeFromNib方法,用哪個都可以币狠,但是如果是添加子控件用initWithCoder方法游两,如果是對子控件進行初始化操作用awakeFromNib方法
- 11.懶加載placeHolderLabel控件,將其添加到ComposeTextView中漩绵,設(shè)置其約束及屬性及文字
- 12.設(shè)置TextView的文本內(nèi)容的內(nèi)邊距屬性textContainerInset贱案,使用決定文字輸入后的文字在什么位置,
- 13.在控制器的ViewDidAppear顯示完成的時候讓TextView成為第一響應(yīng)者彈出鍵盤
- 14.開始輸入文字時止吐,占位Label隱藏宝踪,可以通過代理或通知侨糟,這里我們使用代理,讓控制器成為TextView的代理瘩燥,判斷當(dāng)TextView中有文字就隱藏秕重,沒有文字就顯示,可以使用textView的hasText方法判斷有沒有文字厉膀,而且此時還要判斷是否有文字hasText來決定導(dǎo)航條發(fā)布按鈕是否可以點擊
- 15.滾動textView時溶耘,讓鍵盤隱藏,但此時textView并不能滾動服鹅,原因:雖然textView繼承自UIScrollView凳兵,由于當(dāng)前textView的contentSize內(nèi)容不夠所以不能滾動,但是我們也可以在不設(shè)置contentSize的情況下讓textView滾動企软,有兩個屬性:開啟【Bounce horizontally】可以左右滾動留荔,開啟【Bounce vertically】可以上下滾動,這兩個屬性都是UIScrollView的
- 16.調(diào)用scrollView的滾動代理方法讓textView失去第一響應(yīng)者即可
##
- 17.實現(xiàn)底部工具欄:
     -(1)在XIB中在TextView底部拖一個UIToolBar澜倦,刪除ToolBar中的item聚蝶,拖UIButton進去,因為ToolBar自帶的item沒有點擊時高亮狀態(tài)藻治,設(shè)置約束碘勉,距離底、右桩卵、左為0验靡,ToolBar高度默認(rèn)為44
     -(2)在ToolBar中添加幾個需要的Button,但是我們需要Button之間有間距雏节,如果使用彈簧的話兩邊距離控制器view間距會變得很大胜嗓,如果不希望這兩邊間距很大,可以使用小技巧:往view兩邊與按鈕之間各拖入一個item钩乍,刪除item的文字辞州,給item輸入幾個固定的空格即可
     -(3)當(dāng)鍵盤彈出時,讓toolBar一起上移:監(jiān)聽鍵盤即將改變frame的通知
##
- 18.選中照片的布局
     -(1)ToolBar上第一個按鈕點擊可以選照片
      點擊選中照片時:第一先退出鍵盤寥粹,第二彈出一個界面可以選擇照片变过,這個界面并沒有將工具欄隱藏及蓋上,反而工具欄在最底部涝涤,界面上有一個?按鈕媚狰,點擊后彈出相冊可以選照片
     -(2)在XIB上面拖一個CollectionView,讓它在ToolBar的后面(不要蓋住ToolBar)阔拳,默認(rèn)情況下設(shè)置約束為左崭孤、右、底部(view)、高度為0辨宠,目的是默認(rèn)不顯示出來遗锣,當(dāng)點擊ToolBar上的選照片按鈕時改變CollectionView高度約束讓它顯示(最好讓高度約束為屏幕高度的比例0.65)
     -(3)給CollectionView設(shè)置數(shù)據(jù)源,如果讓發(fā)布控制器成為其數(shù)據(jù)源彭羹,那發(fā)布控制器的代碼會很多黄伊,所以我們可以自定義UICollectionView泪酱,讓它來管理XIB的CollectionView派殷,并讓它自己成為自己的代理
     -(4)注冊cell,XIB中CollectionView上沒有cell墓阀,storyboard中CollectionView有cell毡惜,所以只能通過代碼注冊cell類型
     -(5)給collectionView設(shè)置布局,取出collectionView的布局轉(zhuǎn)為流水布局斯撮,設(shè)置一共有3列item经伙,每個item的間距為10,計算item的寬度和高度為(屏幕的寬度 - 4個間距) / 3,這里有個問題:item之間的間距太多勿锅,但是設(shè)置最小間距不好解決帕膜,可以設(shè)置collectionView的contentInset解決,讓邊上的內(nèi)容往里面擠
     -(6)自定義cell類并使用XIB搭建溢十,并讓collectionView的cell注冊為這個XIB垮刹,往XIB上添加兩個按鈕,一個【?】按鈕张弛,一個【X】按鈕荒典,默認(rèn)【X】按鈕隱藏,
     -(7)點擊【?】按鈕時彈出照片選擇器:需要監(jiān)聽【?】按鈕的點擊事件吞鸭,但是由于cell并不是控制器無法彈出照片瀏覽控制器寺董,而cell的父控件是collectionView也不是控制器,但collectionView的父控件是發(fā)布控制器刻剥,這里可以使用代理遮咖、閉包、通知造虏,其中一種方式讓發(fā)布控制器彈出照片瀏覽控制器盯滚,用什么方法會好些呢:由于這里涉及到多層傳遞,多層之間傳遞使用通知最好
     -(8)點擊【?】按鈕時發(fā)布通知酗电,在發(fā)布控制器中注冊通知魄藕,當(dāng)發(fā)布控制器接收到通知后彈出選擇照片控制器
     -(9)顯示選中的照片:在發(fā)布控制器中定義一個UIImage類型的懶加載數(shù)組images變量,當(dāng)選擇照片時撵术,將選中的照片添加到這個數(shù)組中背率,在collectionView中定義一個images變量,然后將這個數(shù)組賦值給collectionView的images,讓collectionView去展示數(shù)據(jù)寝姿,監(jiān)聽collectionView的images發(fā)送改變交排,只要改變就刷新數(shù)據(jù)
     -(10)在cell中定義一個image變量,監(jiān)聽image發(fā)生改變饵筑,只要image發(fā)生改變就將image設(shè)置為?按鈕的背景埃篓,在collectionView中給cell的image傳值
     -(11)存在問題:collectionView上選擇后的照片被壓扁了,這里不能通過改變?按鈕的contentModl來解決根资,因為當(dāng)前是把照片設(shè)置在?按鈕的背景上了架专,并不是按鈕內(nèi)部的圖片上
          解決步驟:
          (1)在XIB中拖一個imageView到加號按鈕上面(不是子控件哦),且在刪除按鈕后面玄帕,不能蓋住刪除按鈕部脚,設(shè)置這個imageView的contentModl為填充Fill模式,并將其拖線到cell中裤纹,然后給其設(shè)置圖片即可
          (2)在監(jiān)聽cell的image屬性發(fā)送改變時委刘,當(dāng)有圖片就把圖片設(shè)置給這個imageView,不要設(shè)置給?按鈕了鹰椒,防止循環(huán)利用锡移,沒有圖片時設(shè)置imageView的image為nil
          (3)當(dāng)有時明明把刪除按鈕放在了imageView的上面,但是還是不顯示刪除按鈕時漆际,可以嘗試在XIB中拖動下imageView的順序淆珊,在拖回去,這一般是小bug
##
- 19.刪除選中照片
     -(1)刪除選中照片的按鈕默認(rèn)設(shè)置為隱藏灿椅,并在cell的image監(jiān)聽器中根據(jù)只要image不為nil就讓刪除按鈕顯示套蒂,image為nil時隱藏
     -(2)將刪除按鈕拖線到cell中,點擊刪除按鈕時刪除這張照片茫蛹,刪除照片應(yīng)該從發(fā)布控制器的images數(shù)組中刪除操刀,刪除后刷新表格
     -(3)由于刪除按鈕的點擊事件是在cell類中,要想點擊了cell上按鈕讓控制器去做事情時婴洼,可以使用通知骨坑,這里就發(fā)布一個點擊了刪除按鈕的通知,然后在發(fā)布控制器中監(jiān)聽這個通知柬采,接收到通知后將當(dāng)前點擊刪除按鈕上的image從images數(shù)組中刪除欢唾,然后刷新表格
     -(4)問題:點擊刪除按鈕要刪除對應(yīng)的那個照片,但是那個照片在數(shù)組中的索引我們并不知道
         解決方法:
           (1)在發(fā)布通知時粉捻,將點擊的imageView.image通過object參數(shù)傳出去礁遣,
           (2)在接收到通知的方法中,通過object參數(shù)獲取這個image肩刃,當(dāng)然也可以通過發(fā)布通知的userInfo參數(shù)傳出來祟霍,但是userInfo一般適合傳多個參數(shù)的杏头,所有使用object參數(shù)
           (3)通過object參數(shù)獲取的是AnyObject的可選對象,需要使用guard做校驗沸呐,獲取不到就return醇王,校驗的同時并轉(zhuǎn)為UIImage對象
           (4)通過images數(shù)組調(diào)用indexOf方法將這個image傳進去就可以獲取這個image在images數(shù)組中的下標(biāo)值(索引),獲取的是可選類型崭添,需要使用guard做校驗寓娩,獲取不到就return
     -(5)通過獲取的下標(biāo)值將其從images數(shù)組中remove掉
     -(6)重新把移除后的images數(shù)組賦值給collectionView的images
     -(7)其實重新賦值完成后,collectionView的images值就會發(fā)生變化呼渣,此時它的監(jiān)聽器監(jiān)聽到發(fā)生改變后就會調(diào)用reloadData刷新表格棘伴,就會更新界面
##
- 20.點擊toolBar上的表情按鈕時,切換鍵盤為表情鍵盤徙邻,再點擊表情按鈕時排嫌,鍵盤再切換回去畸裳,【切換鍵盤要通過UITextView或UITextField的[inputView]屬性設(shè)置缰犁,當(dāng)設(shè)置為nil時就是默認(rèn)的普通鍵盤哦】
     -(1)監(jiān)聽toolBar上表情按鈕的點擊,拖線到發(fā)布控制器中
     -(2)當(dāng)點擊表情按鈕時:(1.先退出鍵盤 2.切換鍵盤怖糊,3.彈出鍵盤)
     -(3)注意:要想切換鍵盤帅容,必須要先將鍵盤退出,才能切換伍伤,切換以后再彈出切換好的鍵盤
     -(4)切換鍵盤可以通過判斷textView的inputView是否為nil并徘,當(dāng)為nil時就設(shè)置為自定義的鍵盤,不為nil時就讓其為nil(nil時鍵盤為默認(rèn)的普通鍵盤)扰魂,所以可以使用三目運算符做判斷
## 
- 21.自定義表情鍵盤Emoticon
    建議:由于表情鍵盤做起來比較復(fù)雜麦乞,可以單獨創(chuàng)建一個項目,并與當(dāng)前項目界面差不多劝评,然后在新的項目中封裝好以后姐直,再拖到這個項目中使用即可
     -(1)由于表情鍵盤上的業(yè)務(wù)邏輯較為復(fù)雜,需要自定義一個控制器來管理鍵盤表情蒋畜,讓inputView成為控制器的view,并且專門給器創(chuàng)建一個文件夾
     -(2)自定義一個EmoticonViewController類声畏,繼承自UIViewController,如果想要把某個單獨功能封裝起來方便其他項目再次使用的話姻成,最好不要使用XIB
Snip20161002_16.png
   -(3)Emoticon鍵盤分為兩個部分:上面為表情插龄,下面是工具欄(選擇表情類型的),上面的部分可以使用collectionView,因為每個表情就可以是一個cell科展,下面的控件用ToolBar
   -(4)在EmoticonViewController控制器中均牢,添加這兩個控件,先進行懶加載才睹,注意collectionView需要布局徘跪,懶加載時給其傳一個布局见秤,由于frame不確定,所以可以使用CGRectZero
   -(5)在viewDidLoad方法中添加兩個子控件真椿,通過代碼給子控件設(shè)置約束鹃答,封裝功能或框架最后不要使用第三方框架,不然產(chǎn)生依賴突硝,不方便拿到其他項目中復(fù)用
   -(6)注冊cell和設(shè)置collectionView的數(shù)據(jù)源為當(dāng)前控制器
   -(7)設(shè)置collectionView的布局测摔,直接在當(dāng)前控制器中,自定義EmoticonCollectionViewLayout解恰,繼承自UICollectionViewFlowlayout
      -(1)重寫prepareLayout方法(準(zhǔn)備布局時調(diào)用)锋八,在這個方法中#1先計算每個item的寬高,由于當(dāng)前需求每個item之間沒有間距护盈,且每列有7個item挟纱,所有寬高等于屏幕的寬度除以7即可,然后設(shè)置為itemSzie腐宋,最小間距為0紊服。#2設(shè)置collectionView的相關(guān)屬性
          此時有個問題:每行item之間有間隔,雖然設(shè)置了最小間距為0胸竞,但是大于0也是成立的欺嗤,所以產(chǎn)生間隔正常,如果不要這個分割卫枝,可以設(shè)置collectionView的contentInset煎饼,讓它的頂部和底部有這個間距內(nèi)邊距,間隔高度的的計算方法:collectionView的高度除以3(共3行)行item的高度校赤,再除以2即可
     注意:如果使用自定義的布局吆玖,在創(chuàng)建的collectionView時也要使用這個自定義的布局類來創(chuàng)建,不然等于白做
## 
- 22.表情鍵盤上的toolBar
    -(1)先定義一個標(biāo)題數(shù)組專門存放toolBar上的標(biāo)題字符串
    -(2)遍歷標(biāo)題數(shù)組马篮,取出每一個標(biāo)題沾乘,遍歷時創(chuàng)建UIBarButtonItem添加到toolBar上,并把每個標(biāo)題設(shè)置為UIBarButtonItem的title积蔚,綁定每個UIBarButtonItem的tag為遍歷的索引
     注意:(1)如果將創(chuàng)建的UIBarButtonItem添加到toolBar的items屬性中不能顯示toolBar上的按鈕時意鲸,可以將創(chuàng)建的UIBarButtonItem先添加到一個臨時[UIBarButtonItem]類型數(shù)組,再將這個臨時數(shù)組賦值給toolBar的items屬性
    -(3)創(chuàng)建UIBarButtonItem時尽爆,每添加一個彈簧怎顾,但是最后一個不需要彈簧,可以在創(chuàng)建好以后漱贱,從toolBar的items數(shù)組中刪除最后一個
## 
- 23.加載表情數(shù)據(jù)
     -(1)emoticon表情其實就是字符串槐雾,一般存儲在一個plist文件中,對應(yīng)的code就是emotion的字符串幅狮,但是需要轉(zhuǎn)換 募强,浪小花和默認(rèn)表情是png圖片
     -(2)表情分為:默認(rèn)表情株灸、emoticon表情、浪小花表情擎值、最近表情慌烧,所以創(chuàng)建模型時要有對應(yīng)的組,
     -(3)創(chuàng)建3個模型:第1個是EmoticonManager模型用來管理所有的組的(4個組)鸠儿,第2個是EmoticonPackage組模型屹蚊,組里面放的是每一個的表情模型,第3個是Emoticon表情的模型进每,每一個表情也是一個模型
##
- 24.自定義cell展示表情
##
- 25.每20個表情后面添加一個刪除按鈕:
     -(1)修改模型:在EmoticonPackage添加模型的代碼中汹粤,判斷當(dāng)索引為20時,添加一個刪除表情按鈕模型田晚,并且把索引重置為0
##
- 26.如果是第一中類型表情一共107個嘱兼,顯示5頁,每頁21個贤徒,這樣會空兩個出來沒有表情
解決方法:添加空白表情芹壕,拿到所有表情的個數(shù) 抹去% 21,當(dāng)%后的值沒有的話,就沒有空白泞莉,不用添加哪雕,當(dāng)%后有值船殉,就添加21-抹去后的值的個數(shù)
注意:最近分組也需要添加空白表情
## 
- 27.當(dāng)選中一個表情時不光有插入到文本鲫趁,還有放到最近表情里面
     -(1)監(jiān)聽cell的點擊:設(shè)置cell的代理方法,
     -(2)取出點擊表情模型
     -(3)將點擊的表情模型插入到最近分組中利虫,但是需要判斷如果是空白表情或刪除按鈕挨厚,只要有其中一個都不需要插入
     -(4)將點擊的模型表情插入到最新分組的第0個位置,但是在插入之前要刪除一個表情糠惫,判斷最新分組中有沒有包含點擊的那個表情疫剃,如果有包含表示原來有這個表情,當(dāng)沒有包含原來的表情時硼讽,就remove第19個(因為索引從0開始巢价,第20個是刪除按鈕,所以刪除倒數(shù)第二個)固阁,如果包含原來的表情壤躲,就刪除自己
##
- 28.點擊emoticon表情時,將表情插入到文本輸入框中
        這里說的外面是外界調(diào)用我封裝好的這個emoticon的控制器备燃,內(nèi)部指的就是emoticonViewController
     -(1)分析:插入的輸入框一般在最外界的控制器里面碉克,需要在當(dāng)我點擊這個表情時,將表情回調(diào)到外面的控制器中
     -(2)采取閉包的方式回調(diào):在外面封裝一個閉包(閉包就是一個{代碼塊}并齐,去內(nèi)部拿到閉包的引用漏麦,之后通過這個閉包的引用來調(diào)用閉包客税、執(zhí)行閉包
     -(3)點擊某個表情時回調(diào)到外面:在創(chuàng)建emoticonViewController時,就傳進去一個閉包撕贞,可以重寫emoticonViewController構(gòu)造函數(shù)更耻,在參數(shù)中添加一個閉包,因為有可能還有在其他地方使用這個閉包可以emoticonViewController中定義一個屬性保存這個閉包捏膨,由于需要將emoticon模型傳到外界酥夭,所以閉包中添加一個emoticon模型參數(shù),注意:自定義控制器的構(gòu)造函數(shù)脊奋,必須調(diào)用super設(shè)計好的構(gòu)造方法super.init(inbName:nil bundle:nil)
     -(4)在collectionView的代理方法中當(dāng)點擊了表情時熬北,調(diào)用閉包并傳入點擊的表情模型,就完成回調(diào)閉包
     -(5)當(dāng)外界需要拿到emoticonViewController的view設(shè)置為鍵盤時诚隙,需要先通過剛剛的自定義構(gòu)造函數(shù)創(chuàng)建讶隐,通過里面的閉包的參數(shù)就可以拿到內(nèi)部傳遞出去的表情
     -(6)注意循環(huán)引用:由于在外界要使用這個閉包回調(diào)的表情模型參數(shù)設(shè)置給當(dāng)前控制器self.textView控件,此時外界就對閉包產(chǎn)生強引用久又,那內(nèi)部emoticonViewController也對閉包產(chǎn)生強引用巫延,就會導(dǎo)致循環(huán)引用,所以在外界要使用weak self來修飾
     -(7)emoji表情不需要做圖文混排地消,因為本身就是字符串炉峰,普通表情需要圖文混排
     -(8)插入表情到文本輸入框光標(biāo)所在的位置
        -1.先判斷是不是空白表情,如果是就return
        -2.判斷是不是刪除按鈕脉执,如果是先刪除光標(biāo)前面的文字:textView.delegateBackward疼阔,然后return
        -3.判斷是不是emoji表情,如果是就獲取光標(biāo)所在的位置半夷,再把光標(biāo)所在的位置替換為emoji表情婆廊,然后return
          注意:外界使用時一定要先取出emoticonViewController的view,再給textView設(shè)置inputView為它的view巫橄,不然不會顯示
##
- 29.圖文混排實現(xiàn)
     創(chuàng)建圖文混排的類是NSTextAttachment,屬性字符串的類NSAttributedString淘邻,通過創(chuàng)建一個屬性字符串時,將NSTextAttachment類的images傳進一個屬性字符串中湘换,由于屬性字符串之間不能相加拼接宾舅,還需要創(chuàng)建NSMutableAttributedString可變的屬性字符串,然后將圖文混排的屬性字符串與普通的屬性字符串之間拼接彩倚,最后將拼接后的屬性字符串賦值給控件的attributedText屬性
## 
- 30.通過圖文混排將普通表情添加到文本輸入框中
        -(1).根據(jù)表情圖片的全路徑pngPath創(chuàng)建圖文混排的屬性字符串
        -(2).如果直接將創(chuàng)建好的圖片屬性字符串直接賦值給textView的attributedText屬性筹我,就會將teextView上所有的文字全部替換掉了,我們想要的效果是署恍,將圖片屬性字符串替換到光標(biāo)所在的位置崎溃,所以我們需要先拿到textView的attributedText屬性,就等于拿到了textView上的所有文本盯质,然后將其轉(zhuǎn)為可變的屬性字符串袁串,如果表情太大可以將textView的font取出概而,將字體的lineHeight設(shè)置為圖片混排的bounds屬性即可
        -存在的問題1:當(dāng)輸入表情后,文字會跟隨表情的大小而改變字體大小
        -解決方法:設(shè)置表情的大小時囱修,先取出textView的字體用常量保存赎瑰,設(shè)置完成后,再將取出的這個字體賦值回去給textView的font即可
        -存在的問題2:選擇某個表情替換到textView的指定位置后破镰,光標(biāo)跑到文本的最后面了
        -解決方法:將光標(biāo)設(shè)置回原來的位置+1餐曼,就是插入的表情后面,設(shè)置textView的selectedRange屬性
##
- 31.獲取表情文字字符串
        -(1)當(dāng)點擊發(fā)布按鈕時鲜漩,會將編輯好的文本發(fā)送到服務(wù)器源譬,假如文本中有表情的話,是不能圖片屬性字符串將其發(fā)送到服務(wù)器的孕似,應(yīng)該將表情替換為對應(yīng)文字
        -(2)當(dāng)點擊發(fā)布按鈕時踩娘,獲取textView的屬性字符串,在遍歷屬性字符串
##    
- 32.封裝插入和獲取表情的方法:
        插入表情是往textView中插入喉祭,獲取表情是從textView中獲取养渴,由于都是和textView有關(guān)系,可以先給textView擴充Extension泛烙,再給textView擴充兩個方法:給textView插入表情方法和獲取textView屬性字符串對應(yīng)的表情字符串方法
##
- 33.項目集成表情鍵盤
      將單獨封裝的emoticon拿到項目中使用即可
      - 問題1: 插入表情時理卑,占位文字需要隱藏掉
      - 解決方法: 這是因為插入表情時,并沒有觸發(fā)textView的代理方法蔽氨,可以在插入表情時藐唠,主動調(diào)用textView的代理方法
##
- 34.點擊發(fā)布按鈕時,發(fā)布一條文字微博
      - (1)到新浪開發(fā)者網(wǎng)站找到微博接口孵滞,里面有寫入接口掏父,找到發(fā)布一條微博
      - (2)在網(wǎng)絡(luò)工具類中凉倚,寫一個發(fā)微博的方法
##
- 35.點擊發(fā)布按鈕時,發(fā)布一條圖片文字微博
       -(1)如果點擊發(fā)布按鈕發(fā)送的是圖片微博挫望,需要更換接口為上傳拖并發(fā)布一條微博殴蓬,這個接口只能發(fā)一張圖片匿级,因為當(dāng)前項目使用的是授權(quán)方式,而不是官方api接口
       -(2)在網(wǎng)絡(luò)工具類中染厅,寫一個發(fā)送微博并且攜帶圖片的方法
## 
- 36.正則表達式
       -(1)創(chuàng)建正則表達式規(guī)則
       -(2)創(chuàng)建正則表達式對象痘绎,(一般使用regex常量名),注意:創(chuàng)建時方法后面有throws肖粮,是拋出異常孤页,需要使用try? 、try!涩馆、try處理異常行施,一般使用try?允坚,返回的是可選類型需要進行校
       -(3)匹配字符串內(nèi)容,想整個字符串都進行匹配蛾号,可以從0的位置loction開始匹配稠项,到這個字符串長度lenght,switft中要想拿到字符串的鲜结,可以通過字符串的characters.count獲取展运,匹配的結(jié)果會在數(shù)組中返回
       -(4)遍歷匹配結(jié)果數(shù)組,獲取結(jié)果
       swift中如果字符中寫\會報錯精刷,可以在\后面在加一個\進行轉(zhuǎn)譯就可拗胜,也就是兩個\\
##
微博表情顯示
-(1)分析:微博正文一般會有表情需要顯示,但是客戶端發(fā)送給服務(wù)器的一般是類似[哈哈]文字的怒允,其實[哈哈]在表情info.plist中是chs挤土,我們可以通過chs獲取表情的pngPath圖片路徑,通過圖片路徑創(chuàng)建UIImage對象误算,在通過UIImage對象創(chuàng)建NSTextAttachment仰美,再根據(jù)NSTextAttachment創(chuàng)建屬性字符串,最終顯示的是屬性字符串
使用圖片瀏覽器展示微博圖片
## 一儿礼、點擊圖片時咖杂,將圖片所在的控件cell的數(shù)據(jù)傳遞給圖片瀏覽器
-(1)需求:點擊微博上的圖片時,進入圖片瀏覽器蚊夫,圖片可以滾動查看下一張诉字,當(dāng)從第一張圖片開始展開,瀏覽到其他位置圖片時知纷,點擊關(guān)閉按鈕壤圃,圖片會以動畫顯示到點擊關(guān)閉的那個圖片
-(2)圖片是在collectionViewCell上的,所以需要監(jiān)聽cell的點擊琅轧,設(shè)置cell的代理伍绳,由于cell是UIView不能彈出控制器,所以當(dāng)cell發(fā)生點擊時通知homeViewController來彈出控制器(原則:內(nèi)部子控件發(fā)生點擊通知外界來做事情)
-(3)使用通知的方式通知外界:由于cell的父控件是collectionView乍桂,collectionView的父控件是tableViewCell冲杀,tableViewCell的父控件是tableView,tableView的父控件才是homeViewController睹酌,層級關(guān)系比較多权谁,所以最好使用通知
-(4)點擊cell時發(fā)布通知,并傳遞參數(shù)
-(5)獲取通知需要傳遞的參數(shù):1.點擊圖片是第幾個:index憋沿,2. 所有圖片的url:picURLs旺芽,當(dāng)數(shù)據(jù)比較多放大通知的userInfo參數(shù)里,當(dāng)數(shù)據(jù)只有一個對象時就放到通知的object參數(shù),注意:通知名和需要傳遞的參數(shù)的key要寫成常量采章,這是開發(fā)規(guī)則
-(6)在HomeViewController中監(jiān)聽通知
-(7)自定義photoBrowserViewController(圖片瀏覽器)运嗜,繼承自UIViewController
-(8) homeViewController中接收cell發(fā)來的通知時,彈出photoBrowserViewController
-(9)在監(jiān)聽通知方法中需要通過key取出cell傳遞的數(shù)據(jù)共缕,然后傳遞給photoBrowserViewController
-(10)#在photoBrowserViewController類中自定義init構(gòu)造函數(shù)洗出,并添加兩個參數(shù):picURLs和indexPath,這樣外界在使用photoBrowserViewController創(chuàng)建對象時图谷,就必須要傳入這兩個參數(shù)才可以翩活,注意:由于當(dāng)前自定義控制器的init構(gòu)造函數(shù),所有必須調(diào)用super的init(initName:nil,bundle:nil)
-(11)#在photoBrowserViewController類中定義兩個屬性便贵,用于保存外界傳遞的indexPath和picURLs菠镇,注意:在自定義的構(gòu)造函數(shù)中需要將init的參數(shù)賦值給定義的這兩個屬性,這樣最終就實現(xiàn):當(dāng)外界創(chuàng)建photoBrowserViewController時就會先將indexPath和picURLs傳遞進去承璃,然后再賦值給了photoBrowserViewController的兩個參數(shù)利耍,那么就可以在類中使用這兩個參數(shù)了
##二、在圖片瀏覽器中展示微博圖片
-(1)圖片瀏覽器界面分析:由于圖片可以拖動切換下一張盔粹,頂部還有兩個控件關(guān)閉和保存按鈕隘梨,拖動圖片的控件使用collectionView,每個圖片就是一個cell舷嗡,關(guān)閉和保存按鈕使用UIButton轴猎,所以共三個控件
-(2)photoBrowserViewController中懶加載這三個控件并創(chuàng)建
-(3)設(shè)置UI界面:1.添加這三個子控件到控制器view上(注意要先添加collectionView,再添加兩個button进萄,不然collectionView會蓋住這兩個button)捻脖,2.設(shè)置frame,collectionView占據(jù)整個view可以設(shè)置為view的bounds中鼠,兩個按鈕在底部可以使用約束設(shè)置可婶,3.設(shè)置兩個按鈕的背景顏色、文字援雇、及字體大小矛渴,由于設(shè)置button的代碼較多,可以在UIButton的Extension分類中熊杨,給UIButton增加一個便利構(gòu)造函數(shù)init曙旭,在init中添加這三個參數(shù),便利構(gòu)造函數(shù)里面是調(diào)用self的init(),而不是super的哦晶府,在便利構(gòu)造函數(shù)中把這三個參數(shù)設(shè)置為UIButton的相關(guān)屬性即可,那這樣就可不用在初始化UI界面的設(shè)置關(guān)閉和保存按鈕的屬性了钻趋,在懶加載時使用構(gòu)造函數(shù)創(chuàng)建出來就可以設(shè)置了川陆,
-(4)設(shè)置collectionView的數(shù)據(jù)源及注冊collectionView: cell的個數(shù)就是picURLs數(shù)組的總個數(shù)
-(5)自定義的流水布局并在創(chuàng)建collectionView時使用這個自定義的布局,重寫prepare方法(準(zhǔn)備布局時調(diào)用):1.設(shè)置itemSize為collectionView的size(占據(jù)屏幕)蛮位,滾動方向為水平滾動
-(6)自定義collectionViewCell并在注冊collectionView的cell時使用自定義的cell较沪,
-(7)在自定義cell中定義picURL屬性鳞绕,把collectionView的picURLs對應(yīng)的url傳遞給cell,讓cell自己去展示圖片
-(8)重寫cell的initWithFrame構(gòu)造函數(shù)添加子控件尸曼,給cell的contentView添加scrollView们何,給scrollView添加imageView展示圖片:為什么使用scrollView,這是因為控轿,有些長圖片是需要上下滾動查看的冤竹,注意:1.子控件使用懶加載的方式創(chuàng)建2.imageView需要根據(jù)圖片的比例設(shè)置frame,目前已經(jīng)image的x值0茬射,寬度為屏幕的寬度鹦蠕,未知y和高度,由于每個圖片大小不同在抛,無法固定器frame钟病,所以需要在cell的picURL屬性監(jiān)聽器didSet中設(shè)置,只要圖片發(fā)送了改變刚梭,就根據(jù)圖片的等比例去計算高度及y值肠阱,不過y值分兩種情況1是當(dāng)圖片的高沒有超過屏幕時就讓其居中,當(dāng)超過屏幕高度時y值就為0朴读,圖片的真實高度需要通過SDWebImage從沙盒緩存中獲取出image就能拿到真實寬高
-(9)設(shè)置imageView的image從沙盒中取出的圖片屹徘,即可展示圖片了
##三、下載大圖及繪制下載圖片進度
-(1)由于當(dāng)前展示的圖片的url是縮略圖的磨德,導(dǎo)致展示的圖片非常模糊缘回,所以在設(shè)置imageView的image時需要設(shè)置為大圖片
-(2)新浪的圖片URL是有規(guī)則的:小圖的URL有thumbnail字符,中圖有bmiddle典挑,大圖是large酥宴,所以我們把小圖的url字符串中thumbnail字符替換為bmiddle就可以獲取大=中圖的url
-(3)繪制圖片的下載進度:
   -1.自定義ProgressView繼承自UIView,使用drawRect方法繪制一個圓
   -2.創(chuàng)建貝塞爾曲線對象進行繪制
   -3.在cell類中懶加載ProgressView您觉,并將ProgressView添加到cell的contentView上拙寡,設(shè)置ProgressView的center為cell的屏幕的中心點,寬高為50
  -4.讓ProgressView默認(rèn)隱藏琳水,并清空背景顏色
  -5.當(dāng)下載圖片時顯示ProgressView肆糕,下載完成后隱藏
##四、問題解決
-(1).當(dāng)點擊微博的圖片時在孝,不管點擊的哪一張展示的都是第一張圖片
     -解決方法:在photoBrowserViewController中讓collectionView滾動到對應(yīng)的位置诚啃,調(diào)用collectionView的scrollToItemAtIndexPath方法,然后將之前保存的indexPath屬性傳進去私沮、再傳入左對齊始赎、不需要動畫,即可
-(2).每張圖片之間的挨的太緊不美觀,讓圖片之間產(chǎn)生間距
     -解決方法:設(shè)置photoBrowserViewController的view.frame.size+=20,重寫loadView方法中設(shè)置造垛,再在cell中設(shè)置scrollView.frame.size.width -= 20魔招,注意:不要通過bounds來修改,一定要使用frame五辽,不然會出現(xiàn)問題办斑,這是因為修改bounds的width時,會以中心點為原點杆逗,控件的左邊加10的寬乡翅,右邊加10的寬,而frame是以左上角為原點增加寬度髓迎,所以最終是右邊加20寬度
-(3).點擊圖片時關(guān)閉圖片瀏覽器
   -分析:設(shè)置cell的代理峦朗,didSelectItemAtIndexPath方法中調(diào)用closeButtonClick,但是此時點擊圖片時并沒有反應(yīng)排龄,這是因為imageView的父控件把事件劫走了波势,而且我們想要的消失是只有點擊圖片才可以退出界面,點擊圖片以外的無反應(yīng)橄维,所以最終是給imageView添加點按手勢
   -解決方法:當(dāng)點擊imageView時尺铣,通知cell的代理關(guān)閉圖片瀏覽器
   -1.創(chuàng)建代理協(xié)議
     protocol XYPhotoBrowerCellDelegate {
             func photoBrowerImageViewClick()
       }
     var delegate : XYPhotoBrowerCellDelegate?  // 代理屬性

##五、點擊保存按鈕時將圖片保存到相冊中
-(1).獲取當(dāng)前正在顯示的image:通過collectionView的visbibleCells争舞,這個方法會返回所有在顯示的cell的數(shù)組凛忿,由于當(dāng)前正在顯示的只要一個imageView,所以可以取出數(shù)組中first竞川,通過cell獲取到imageView的image

##六店溢、自定義彈出和消失動畫
-(1).需求當(dāng)點擊圖片時,從圖片的位置慢慢放大顯示圖片委乌,而且圖片后面的界面不可以消失
   -解決方法(一床牧、設(shè)置漸變效果顯示和關(guān)閉控制器):
     1.修改modal的彈出樣式presentationStyle為自定義custom,這樣在modal出控制器時就不會隱藏控制器的view了
     2.使用自定義轉(zhuǎn)場遭贸,讓圖片位置慢慢放大圖片戈咳,設(shè)置轉(zhuǎn)場代理
     3.創(chuàng)建PhotoBrowerAnimation類繼承自NSObject,用于管理轉(zhuǎn)場動畫
     4.在Home控制器中壕吹,懶加載屬性PhotoBrowerAnimation對象著蛙,在彈出圖片瀏覽器的方法中,設(shè)置圖片瀏覽器photoBrowerVc的轉(zhuǎn)場代理為PhotoBrowerAnimation對象耳贬,在PhotoBrowerAnimation類中實現(xiàn)轉(zhuǎn)場的代理方法
-(2).從圖片的位置慢慢放大顯示圖片踏堡,而且圖片后面的界面不可以消失
   -解決方法(最終方法):
     1.需要拿到三個東西:(1)圖片開始始frame,(2)最終要顯示在照片瀏覽器中的frame咒劲,(3)臨時創(chuàng)建一個imageVew用于做動畫的
     2.把這個臨時的imageView的frame設(shè)置為圖片開始的frame暂吉,然后將imageView慢慢放大到圖片顯示瀏覽器中的frame胖秒,放大完后再移除這個臨時imageView
     3.由于我們是在XYPhotoBrowerAnimation類中執(zhí)行動畫的缎患,而這里拿不到圖片的起始和最終frame及圖片本身
     4.面向協(xié)議開發(fā):可以找一個人幫我拿這些東西(swift和oc叫做面向協(xié)議開發(fā))慕的,(1)在XYPhotoBrowerAnimation中定義協(xié)議protocol,繼承自基協(xié)議NSObjectProtocol挤渔,目的:讓別人準(zhǔn)守協(xié)議肮街,只要別人遵守這個協(xié)議,就可以有協(xié)議中的方法判导,那最終就可以通過協(xié)議方法拿到想要的東西
     5.協(xié)議中提供三個方法:用于獲取開始位置嫉父、最終位置、以及獲取UIImageView對象的三個方法眼刃,再提供代理屬性绕辖,代理屬性必須遵守協(xié)議
     6.起始位置只有cell的父控件picCollectionView可以提供,讓picCollectionView遵守協(xié)議擂红,并實現(xiàn)協(xié)議中的三個方法
     7.讓picCollectionView成為XYPhotoBrowerAnimation的代理:在picCollectionView中發(fā)布顯示圖片瀏覽器的通知中仪际,把picCollectionView自己傳入object通知參數(shù)中,然后在HomeViewController接收到通知的方法中昵骤,取出這個object就是picCollectionView树碱,然后就可以設(shè)置XYPhotoBrowerAnimation的代理為picCollectionView了,
     8.在XYPhotoBrowerAnimation中定義一個indexPath屬性变秦,將HomeViewController中的indexPath賦值給他成榜,這樣完成傳值
     9.獲取起始的frame:picCollectionView中cell相對于整個屏幕的frame,所以我們需要先通過cellForItemIndexPath獲取cell蹦玫,再將cell的frame轉(zhuǎn)換坐標(biāo)為相對keyWindow的frame
     10.獲取結(jié)束位置:先通過indexPath拿到picURLs中對應(yīng)的額圖片url赎婚,可以通過SDWebImage獲取url對應(yīng)的圖片,然后再計算長圖時圖片的frame樱溉,短圖時圖片的frame
     11.獲取UIImageView對象: 先創(chuàng)建UIImageView對象挣输,再通過SDWebImage從磁盤中獲取image,設(shè)置imageView的屬性:將獲取的image設(shè)置為imageView的image饺窿,并設(shè)置contentMode為按照原來的寬高比填充scaleAspectFill歧焦,如果有超出的部分剪掉,然后返回這個imageView即可
     12.在彈出動畫方法中拿到起始frame和結(jié)束frame肚医,將這iamgeView添加到容器視圖中绢馍,給imageView做從起始到結(jié)束frame的動畫效果,動畫結(jié)束后讓這個imageView從父控件中移除
##七肠套、消失動畫
-(1).需求:點擊照片瀏覽器中圖片或關(guān)閉按鈕時舰涌,圖片從照片瀏覽器中慢慢消失到圖片在HomeviewController中的位置
-(2).分析:做消失動畫我們需要兩個東西,一個是當(dāng)前即將消失的圖片在photoBrower中的indexPath你稚,另外一個是需要一個臨時的imageView瓷耙,讓imageView的frame與photoBrowerCell的imageView的frame相同朱躺,并把photoBrower中cell的imageView的image賦值給臨時imageView的image,那我們拿到這兩個屬性后就可以直接做消失動畫了
-(3).誰做消失動畫的代理做合適:photoBrowerController搁痛,因為cell的父控件是collectionView长搀,而collectionView是photoBrowerController的view的子控件,且是在photoBrowerController是collectionView的數(shù)據(jù)源鸡典,所以只有最合適源请,這就是面向協(xié)議開發(fā)

https://github.com/Ossey/WeiBo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市彻况,隨后出現(xiàn)的幾起案子谁尸,更是在濱河造成了極大的恐慌,老刑警劉巖纽甘,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件良蛮,死亡現(xiàn)場離奇詭異,居然都是意外死亡悍赢,警方通過查閱死者的電腦和手機决瞳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泽裳,“玉大人瞒斩,你說我怎么就攤上這事′套埽” “怎么了胸囱?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瀑梗。 經(jīng)常有香客問我烹笔,道長,這世上最難降的妖魔是什么抛丽? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任谤职,我火速辦了婚禮,結(jié)果婚禮上亿鲜,老公的妹妹穿的比我還像新娘允蜈。我一直安慰自己,他們只是感情好蒿柳,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布饶套。 她就那樣靜靜地躺著,像睡著了一般垒探。 火紅的嫁衣襯著肌膚如雪妓蛮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天圾叼,我揣著相機與錄音蛤克,去河邊找鬼捺癞。 笑死,一個胖子當(dāng)著我的面吹牛构挤,可吹牛的內(nèi)容都是我干的髓介。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼儿倒,長吁一口氣:“原來是場噩夢啊……” “哼版保!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起夫否,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎叫胁,沒想到半個月后凰慈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡驼鹅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年微谓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片输钩。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡豺型,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出买乃,到底是詐尸還是另有隱情姻氨,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布剪验,位于F島的核電站肴焊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏功戚。R本人自食惡果不足惜娶眷,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望啸臀。 院中可真熱鬧届宠,春花似錦、人聲如沸乘粒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谓厘。三九已至幌羞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間竟稳,已是汗流浹背属桦。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工熊痴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人聂宾。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓果善,卻偏偏與公主長得像,于是被迫代替她去往敵國和親系谐。 傳聞我的和親對象是個殘疾皇子巾陕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1.圖片瀏覽控件MWPhotoBrowser 實現(xiàn)了一個照片瀏覽器類似 iOS 自帶的相冊應(yīng)用,可顯示來自手機的圖...
    萬忍閱讀 1,500評論 0 6
  • 不以惡小而為之,不以善小而不為茶袒。 小時候梯刚,從我知道這句話的意思開始我就特別喜歡這句話。 也許薪寓,和這句話本身沒有什么...
    嵋一然閱讀 395評論 4 2
  • 《時光》原創(chuàng) 文/紅塵一凡 時光是無情的刻刀亡资, 雕刻出臉上的皺紋, 心上的傷痕向叉! 唯獨驅(qū)趕不了 靈魂的溫情锥腻! 時光...
    37度女人_8dda閱讀 194評論 0 1
  • 我在大部分人眼里也許是個酒鬼少女吧 酒鬼老阿姨也行啦沒差 喜歡酒的香氣和每口淌過舌尖的愉悅感 貪戀酒后自己眼里不用...
    9f9a6c3390cc閱讀 163評論 0 0
  • 雖說是網(wǎng)絡(luò)與新媒體系,但我現(xiàn)在想做的是游戲行業(yè)母谎。由于之前在新東方實習(xí)瘦黑,現(xiàn)在的offer全都是教育行業(yè)。 做運營我覺...
    阿梨阿梨梨閱讀 145評論 0 1