iOS原生二維碼界面的一些注意點(diǎn)

之前的文章是在ViewController里實現(xiàn)了原生二維碼掃描的功能揍拆,后來覺得VC太重了厂财,便把功能抽成了一個View新症,在抽象的過程中也仔細(xì)捉摸了一些沒有仔細(xì)思考過的問題筑凫,特此記錄下來嫌变。

IMG_1130

1.掃描區(qū)域的掃描線動畫

像微信等很多二維碼掃描界面吨艇,總有一個上下移動的掃描線動畫。一開始用我用NSTimer配合view的frame改變實現(xiàn)腾啥,后來發(fā)現(xiàn)不僅容易導(dǎo)致NSTimer的循環(huán)引用东涡,外界調(diào)用也容易開啟多個定時器,已經(jīng)在某些時候動畫會卡頓倘待。便換成了用CABasicAnimation實現(xiàn)疮跑,通過改變view的y值,并把設(shè)置repeatCount為最大凸舵,達(dá)到掃描線上下動的效果祖娘。

- (void)addScanLineAnimation{
    self.scanLine.hidden = NO;
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
    animation.fromValue = @(0);
    animation.toValue = @(self.scanRect.size.height - scanLineWidth);
    animation.duration = scanTime;
    animation.repeatCount = OPEN_MAX;
    animation.fillMode = kCAFillModeForwards;
    animation.removedOnCompletion = NO;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.scanLine.layer addAnimation:animation forKey:scanLineAnimationName];
}


- (void)removeScanLineAnimation{
    [self.scanLine.layer removeAnimationForKey:scanLineAnimationName];
    self.scanLine.hidden = YES;
}

取消時把動畫移除即可。

2.掃描線的漸變色拖尾

這個用CAGradientLayer實現(xiàn)即可啊奄,設(shè)置漸變起始點(diǎn)和終止點(diǎn)渐苏,傳入顏色數(shù)組和對應(yīng)的起始位置(0~1),即可菇夸。

- (UIView *)scanLine{
    if (!_scanLine) {
        _scanLine = [[UIView alloc]initWithFrame:CGRectMake(self.scanRect.origin.x,self.scanRect.origin.y, self.scanRect.size.width, scanLineWidth)];
        _scanLine.hidden = YES;
        CAGradientLayer *gradient = [CAGradientLayer layer];
        gradient.startPoint = CGPointMake(0.5, 0);
        gradient.endPoint = CGPointMake(0.5, 1);
        gradient.frame = _scanLine.layer.bounds;
        gradient.colors = @[(__bridge id)[self.scanLineColor colorWithAlphaComponent:0].CGColor,(__bridge id)[self.scanLineColor colorWithAlphaComponent:0.4f].CGColor,(__bridge id)self.scanLineColor.CGColor];
        gradient.locations = @[@0,@0.96,@0.97];
        [_scanLine.layer addSublayer:gradient];
    }
    return _scanLine;
}

3.設(shè)置AVFoundation原生二維碼類的一些容易崩潰的地方

具體x相關(guān)類別在上篇文章已經(jīng)有所介紹琼富,講講一些容易崩潰的點(diǎn),崩潰主要集中在設(shè)置AVCaptureMetadataOutput的metadaObjectTypes屬性時峻仇,所以在設(shè)置這個數(shù)組時公黑,最好先檢查數(shù)組里的值是否在其availableMetaDataObjectTypes屬性里。像這樣

if (![self.dataOutput.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeQRCode]) {
     NSLog(@"The camera unsupport for QRCode.");
}
self.dataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];

而一般的崩潰是因為availableMetaDataObjectTypes為空摄咆,而造成空的原因是AVCaptureSession沒有addInput和addOutput造成凡蚜。其中input有一個需要注意的地方,在setSessionPreset吭从,也就是取樣的視頻分辨率的時候朝蜘,如果設(shè)置了一個攝像頭不支持的分辨率,那么input是canAddInput會返回NO涩金。并不是所有設(shè)備都支持1080p視頻分辨率的谱醇,所以我們在setSessionPreset時暇仲,可以這樣

if ([self.device supportsAVCaptureSessionPreset:AVCaptureSessionPreset1920x1080]) {
    [self.session setSessionPreset:AVCaptureSessionPreset1920x1080];
}
else{
    [self.session setSessionPreset:AVCaptureSessionPresetHigh];
}    

AVCaptureSessionPresetHigh就是該設(shè)備所支持最高的分辨率。而單純通過設(shè)備ScreenHigh來區(qū)分是否支持1080p視頻分辨率并不可靠副渴,4s以后是支持1080p的奈附,但是還有一些touch設(shè)備,iPad設(shè)備煮剧,已經(jīng)某些后攝像頭壞掉的手機(jī)(會自動調(diào)用前攝像頭斥滤,比如我的5sTAT)上,就會出現(xiàn)分辨率不支持勉盅,canAddInput返回NO佑颇,沒有input,availavleMetadataObjectTypes為空草娜,如果不注意就會產(chǎn)生崩潰挑胸。

4.關(guān)于掃描區(qū)域的正確計算方法

之前提到掃描區(qū)域的interestedRect是一個值是01的CGRect,后來我實驗發(fā)現(xiàn)宰闰,這個01相對的并不是屏幕的Frame茬贵,而是AVCaptureVideoPreviewLayer的Frame值,而我們習(xí)慣把AVCaptureVideoPreviewLayer的frame值等于view的frame值议蟆,從而才在計算時用view的frame值去算百分比闷沥。但后來我發(fā)現(xiàn)正確的轉(zhuǎn)換方法是用AVCaptureVideoPreviewLayer里的metadataOutputRectOfInterestForRect進(jìn)行正常Rect->掃描區(qū)域坐標(biāo)系Rect轉(zhuǎn)換,另外AVCaptureVideoPreviewLayer還提供了rectForMetadataOutputRectOfInterest進(jìn)行掃描區(qū)域Rect->正常坐標(biāo)系Rect的轉(zhuǎn)換咐容,以及CGPoint的相關(guān)轉(zhuǎn)換方法。而且這個轉(zhuǎn)換需要放在session的StartRunning方法之后才會生效蚂维。

[self.session startRunning];
self.dataOutput.rectOfInterest = [self.previewLayer metadataOutputRectOfInterestForRect:self.scanRect];

5.耗時操作放在異步并發(fā)線程中處理

AVFoundation里設(shè)置相機(jī)相關(guān)的方法比較耗時戳粒,可以放在異步并發(fā)線程中處理。

最后

個人封裝了一個CDZQRScanView簡單易用虫啥。支持Cocoapods也可以直接把兩個文件拉進(jìn)項目里蔚约。

所有源碼和Demo

使用時可以把VC兩個文件拖進(jìn)項目里就可。

如果您覺得有幫助,不妨給個star鼓勵一下,歡迎關(guān)注&交流

有任何問題歡迎評論私信或者提issue

QQ:757765420
Email:nemocdz@gmail.com
Github:Nemocdz
微博:@Nemocdz

謝謝觀看

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涂籽,一起剝皮案震驚了整個濱河市苹祟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌评雌,老刑警劉巖树枫,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異景东,居然都是意外死亡砂轻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門斤吐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搔涝,“玉大人厨喂,你說我怎么就攤上這事∽剩” “怎么了蜕煌?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诬留。 經(jīng)常有香客問我幌绍,道長,這世上最難降的妖魔是什么故响? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任傀广,我火速辦了婚禮,結(jié)果婚禮上彩届,老公的妹妹穿的比我還像新娘伪冰。我一直安慰自己,他們只是感情好樟蠕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布贮聂。 她就那樣靜靜地躺著,像睡著了一般寨辩。 火紅的嫁衣襯著肌膚如雪吓懈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天靡狞,我揣著相機(jī)與錄音耻警,去河邊找鬼。 笑死甸怕,一個胖子當(dāng)著我的面吹牛甘穿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梢杭,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼温兼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了武契?” 一聲冷哼從身側(cè)響起募判,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咒唆,沒想到半個月后届垫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钧排,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年敦腔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恨溜。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡符衔,死狀恐怖找前,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情判族,我是刑警寧澤躺盛,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站形帮,受9級特大地震影響槽惫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辩撑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一界斜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧合冀,春花似錦各薇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至棕叫,卻和暖如春林螃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背俺泣。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工疗认, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砌滞。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓侮邀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贝润。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

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