前面寫過一篇關(guān)于圓弧菜單的文章,但是那篇文章里介紹的方法太簡單粗暴,并不適合大數(shù)據(jù)量的載入。后來又通過UICollectionView的流水布局+圓方程重新實現(xiàn)一遍挟纱。計算公式在代碼里。
思路大致是黄琼,(這個是出發(fā)點,可以看一下)
UICollectionView創(chuàng)建一個類似tableView的列表整慎,每個cell的y值是固定的脏款,我在屏幕左邊畫一個圓,這些cell就類似直線裤园,肯定會有和圓相交的地方撤师,通過圓的方程和直線方程代入計算,就可以求出相交點x值拧揽。
下面看一下代碼:
/// 因為item的x值隨范圍變化而實時變化剃盾,在-prepareLayout方法里計算緩存已經(jīng)無用;
/// 需要在下述方法里親自計算來返回布局對象數(shù)組
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
NSArray<UICollectionViewLayoutAttributes *> *attributesArray = [super layoutAttributesForElementsInRect:rect];
CGPoint contentOffset = self.collectionView.contentOffset;
//垂直滾動
CGFloat height = LYSCreenHeight - LYNavigationBarHeight() - LYTabbarHeight();
// 每個點根據(jù)距離中心點距離進(jìn)行縮放
[attributesArray enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * _Nonnull attri, NSUInteger idx, BOOL * _Nonnull stop) {
CGRect myRect = attri.frame;
/*
*圓心和直線相交的計算公式
基本公式:(x-a)*(x-a) + (y-b)*(y-b) = r * r;
推導(dǎo)結(jié)果:x = sqrt(powf(r,2) - powf((y-b),2))+a;
開根號不可有負(fù)數(shù),開之前判斷一下
*/
///radius是半徑,y是獲取當(dāng)前cell所在屏幕的y值,a是圓心的x值,b是圓心的y值
CGFloat radius = height/2 + 120;
//減去contentOffset.y是因為collectionView的y軸偏移量
CGFloat y = myRect.origin.y - contentOffset.y;
CGFloat b = height/2-50;
CGFloat a = -self.collectionView.bounds.size.width*0.65 - 100;
CGFloat sqNum = (powf(radius,2) - powf((y - b),2)) > 0 ? (powf(radius,2) - powf((y - b),2)):0;
CGFloat X = sqrt(sqNum) + a;
myRect.origin.x = X;
attri.frame = myRect;
}];
return attributesArray;
}
主要邏輯在這個方法里淤袜,其他方法與網(wǎng)上實現(xiàn)瀑布流的類似