動(dòng)畫效果
經(jīng)常用UC看到首頁有這么一個(gè)動(dòng)畫,就仿造寫了一下三热。
實(shí)現(xiàn)分析
1.畫曲線的動(dòng)畫
這個(gè)一眼看去就想到用貝塞爾曲線畫,來看貝塞爾曲線方法灾部,給出兩個(gè)定點(diǎn)康铭,和一個(gè)控制點(diǎn)就可以畫。
CGContextAddQuadCurveToPoint(context, 控制點(diǎn)x, 控制點(diǎn)y, 目標(biāo)點(diǎn)x, 目標(biāo)點(diǎn)y);
于是按照下圖赌髓,兩個(gè)黃色的點(diǎn)是定點(diǎn)从藤,綠色的是控制點(diǎn),于是畫出了這樣的圖锁蠕。
看左邊的圖夷野,中間有大片空白,看起來很浪費(fèi)屏幕空間荣倾,用戶體驗(yàn)不太好悯搔,于是想著怎么讓貝塞爾曲線過某個(gè)定點(diǎn),比如讓曲線過綠色的定點(diǎn)舌仍,而不是把控制點(diǎn)設(shè)在綠色的位置妒貌。
重訴一下,現(xiàn)有的方法是給出兩個(gè)定點(diǎn)和一個(gè)控制點(diǎn)铸豁,能畫一條曲線灌曙。
現(xiàn)在是要,已知兩個(gè)定點(diǎn)节芥,和過另外一個(gè)定點(diǎn)D在刺,畫一條曲線逆害。
我現(xiàn)在想讓這條曲線過綠色的點(diǎn),就像下圖那樣蚣驼,求控制點(diǎn)坐標(biāo)是多少魄幕?
看下圖,求出控制點(diǎn)坐標(biāo)的過程
由上圖就得出了控制點(diǎn)的坐標(biāo)颖杏,然后就可以畫出“圖3”的樣子了纯陨,實(shí)際中我覺得圖3貼太緊了,也不美觀输玷,于是 yc 乘了個(gè)0.6的系數(shù)队丝,即 yc = 0.6 * yc,就看起來比較順眼了欲鹏。
2.頁面結(jié)構(gòu)
頁面結(jié)構(gòu)大概是這樣机久,底下的 tableView 鋪滿整個(gè) view,然后藍(lán)色的headerView 加在 tableView 的上面赔嚎,不是加 tableView.tableHeaderView 上面哦膘盖,至于為什么你加加看就知道了。會(huì)跟著 tableview 動(dòng)
3.不規(guī)則事件點(diǎn)擊尤误,事件穿透
headerView 上有一個(gè)頭像侠畔,是可以點(diǎn)擊的,其他地方的點(diǎn)擊事件要傳給底下的 tableView 也叫事件穿透损晤,通過修改 hitTest 可以實(shí)現(xiàn)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
hitTest 主要用來做事件分發(fā)的软棺,可以實(shí)現(xiàn)不規(guī)則點(diǎn)擊,它在整個(gè) view 結(jié)構(gòu)上是遞歸的尤勋,深度優(yōu)先的喘落,今天不講算法,因?yàn)?hitTest 太厲害最冰,不規(guī)則點(diǎn)擊用 pointInside 函數(shù)就夠了瘦棋。
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
這個(gè)函數(shù)會(huì)被 hitTest 調(diào)用,返回 false 表示點(diǎn)擊的不是自己暖哨,返回 true 表示點(diǎn)擊的是自己赌朋。
那么,我只要判斷點(diǎn)擊的 point 在不在頭像的那個(gè)圓圈里面就可以了篇裁,就是判斷點(diǎn)在不在圓內(nèi)沛慢,高中講過了,point 到圓心的距離小于半徑就表示在了达布,那么返回 true 就行团甲。具體的還是看代碼吧。
如果有多個(gè)控件往枣,需要自己確定每個(gè)控件的點(diǎn)擊區(qū)域伐庭。
最后還是上個(gè)代碼 下載地址,下載慢慢看吧分冈。
4.后期改進(jìn)
寫完這個(gè)博客突然想到一個(gè)還要改的地方圾另,就是當(dāng)用戶手指松開的時(shí)候,scrollViewWillEndDragging雕沉,這個(gè)方法內(nèi)判斷一下集乔,contentOffset.y 值,如果超過多少值坡椒,那么自動(dòng)回調(diào)一個(gè) block扰路,可實(shí)現(xiàn)下拉刷新。