剛給UICollectionView寫了個索引view辖试,就像微信聯(lián)系人右邊的字母索引一樣辜王,封裝成了個庫,放在github上LXMCollectionIndexView罐孝;
這里記錄一下其中遇到的問題:
首先說一點感受呐馆,因為之前一段敲的代碼不多,這次寫個控件敲起代碼來居然有點磕磕絆絆莲兢,沒有之前天天寫業(yè)務(wù)代碼時的流暢感汹来,有點讓我意外,果然敲代碼敲的少了也會手生啊改艇,所以不管其他工作有多忙收班,還是得花點時間來敲點代碼~
基本思路是在CollectionView上面添加一個透明的IndexView,indexView的最右邊是字母谒兄,用CALayer或者UILable畫出來摔桦,重寫hitTest方法讓透明部分手勢可以穿透過去,而字母的部分可以響應(yīng)手勢承疲,手勢開始以后邻耕,即使移動到透明部分,也繼續(xù)響應(yīng)手勢燕鸽。注意兄世,這里必須是首先同字母區(qū)域識別出了touch事件再移動到透明區(qū)域才行,直接從透明區(qū)域開始的話绵咱,touch事件會穿透indexView碘饼,不應(yīng)該被indexView識別熙兔。
1,貝塞爾曲線的畫弧線的方法艾恼,一開始畫出來的效果跟自己想象的不一樣住涉,然后從新看了一下文檔,才發(fā)現(xiàn)繪制的方向跟數(shù)學(xué)上學(xué)的不一樣钠绍,文檔上畫了一張圖:
配合clockwise可以畫出任意想要的弧度
2舆声,用到一個iOS10以后才有的類,但工程本身是支持iOS9的柳爽,類的屬性是不支持@available的媳握,只有類或者計算屬性可以聲明@available,那怎么給類添加一個某個版本后才可用的屬性呢磷脯?
在stackOverFlow上找到了個牛逼的方法:
private var _impactFeedbackGenerator: Any? = nil
@available(iOS 10.0, *)
fileprivate var impactFeedbackGenerator: UIImpactFeedbackGenerator {
if _impactFeedbackGenerator == nil {
_impactFeedbackGenerator = UIImpactFeedbackGenerator()
}
return _impactFeedbackGenerator as! UIImpactFeedbackGenerator
}
用計算屬性和一個私有的以為為nil的變量來實現(xiàn)蛾找;
3,直接修改CALayer的屬性赵誓,默認(rèn)是有隱式動畫的打毛,可以用CATransaction的方法來關(guān)閉隱式動畫,如:
CATransaction.begin()
CATransaction.setDisableActions(true)
indicator.alpha = 1
CATransaction.commit()
4俩功,UICollectionView調(diào)用
open func cellForItem(at indexPath: IndexPath) -> UICollectionViewCell?
open func supplementaryView(forElementKind elementKind: String, at indexPath: IndexPath) -> UICollectionReusableView?
方法很可能會取到nil幻枉,但是相應(yīng)的
open func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?
open func layoutAttributesForSupplementaryElement(ofKind kind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?
方法基本上都能取到值,所以可以用后面這兩個方法類確定滑動位置之類的東西
5诡蜓,touch事件的相關(guān)方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
配合
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event; // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event; // default returns YES if point is in bounds
基本可以替代手勢的API熬甫,效果和手勢基本一樣,可以酌情使用