国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > iOS > 正文

iOS彈幕開發(fā)中遇到的問題匯總

2020-07-26 02:33:12
字體:
供稿:網(wǎng)友

前言

彈幕在現(xiàn)在的各類視頻中都有,也是每位開發(fā)者們必須會的一個功能,最近在開發(fā)中就遇到了一些問題,下面簡單說說彈幕開發(fā)碰到的兩個小問題。

正文

  • 需求:實(shí)現(xiàn)一個彈幕容器,里面同時會有多行互不重疊的、運(yùn)動中的彈幕 。每一條彈幕均需要支持點(diǎn)擊事件。
  • 用腳底板想的方法:在彈幕容器里面創(chuàng)建幾個 UIButton,并且 addTarget,增加點(diǎn)擊事件。最后利用 UIView 的 block API 實(shí)現(xiàn)動畫。
  • 結(jié)果:嗯...可惜的是,代碼運(yùn)行起來,你會發(fā)現(xiàn)在 UIButton 運(yùn)動過程,點(diǎn)擊事件并沒有響應(yīng),而且非常奇怪的是:為什么在 UIButton 動畫過程,去點(diǎn)擊 UIButton 動畫的終點(diǎn),點(diǎn)擊事件竟然響應(yīng)了??這是為什么呢?
  • Core Anmation 動畫過程原理的引用:

在iOS中,屏幕每秒鐘重繪60次。如果動畫時長比60分之一秒要長,Core Animation就需要在設(shè)置一次新值和新值生效之間,對屏幕上的圖層進(jìn)行重新組織。這意味著CALayer除了“真實(shí)”值(就是你設(shè)置的值)之外,必須要知道當(dāng)前顯示在屏幕上的屬性值的記錄。

每個圖層屬性的顯示值都被存儲在一個叫做呈現(xiàn)圖層的獨(dú)立圖層當(dāng)中,他可以通過-presentationLayer方法來訪問。這個呈現(xiàn)圖層實(shí)際上是模型圖層的復(fù)制,但是它的屬性值代表了在任何指定時刻當(dāng)前外觀效果。換句話說,你可以通過呈現(xiàn)圖層的值來獲取當(dāng)前屏幕上真正顯示出來的值。

補(bǔ)充:模型圖層在動畫開始的那一刻就已經(jīng)達(dá)到終點(diǎn)位置,響應(yīng)點(diǎn)擊事件的也是它。

解決辦法:

重寫彈幕容器 view 的 touchesBegan 方法。代碼如下:

@interface ZYYBarrageView ()@property (nonatomic, strong) UIView *redView; // 將要做平移的 subview@end@implementation ZYYBarrageView- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) {  [self commonInit]; }   return self;}- (void)commonInit { self.redView = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, 30.f, 30.f)]; self.redView.backgroundColor = [UIColor redColor]; [self addSubview:self.redView];}- (void)touchesBegan:(NSSet<uitouch *> *)touches withEvent:(UIEvent *)event { // 重點(diǎn)開始!!UITouch 獲取在 barrageView 坐標(biāo)系下的坐標(biāo) CGPoint touchPoint = [[touches anyObject] locationInView:self]; // 判斷觸摸點(diǎn)是否在 redView 的呈現(xiàn)樹的框框之中 if ([self.redView.layer.presentationLayer hitTest:touchPoint]) {  // 響應(yīng)紅色塊點(diǎn)擊  return; } else { }}</uitouch *>

進(jìn)一步的需求:在 ZYYBarrageView 的同一層級,但層次偏后會有 UIButton。正常情況下,因?yàn)?ZYYBarrageView 的存在,UIButton 是無法響應(yīng)點(diǎn)擊事件的。代碼如下:

@property (nonatomic, strong) ZYYBarrageView *barrageView; // 彈幕 view 支持多行 view 在里面進(jìn)行運(yùn)動@property (nonatomic, strong) UIButton *yellowBtn; // 靠后的 UIButton- (void)viewDidLoad { [super viewDidLoad];  // self.yellowBtn 位于 self.barrageView 之后 [self.view addSubview:self.yellowBtn]; [self.view addSubview:self.barrageView];}- (ZYYBarrageView *)barrageView { if (!_barrageView) {  _barrageView = [[ZYYBarrageView alloc] initWithFrame:CGRectMake(0.f, 30.f, SCREEN_WIDTH, 30.f)];  _barrageView.backgroundColor = [UIColor clearColor]; }  return _barrageView;}- (UIButton *)yellowBtn { if (!_yellowBtn) {  _yellowBtn = [UIButton buttonWithType:UIButtonTypeCustom];  _yellowBtn.frame = CGRectMake(90.f, 30.f, 80.f, 30.f);  _yellowBtn.backgroundColor = [UIColor yellowColor];  [_yellowBtn setTitle:@"黃色按鈕" forState:UIControlStateNormal];  [_yellowBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  [_yellowBtn addTarget:self action:@selector(onYellowBtn:) forControlEvents:UIControlEventTouchUpInside]; }   return _yellowBtn;}- (void)onYellowBtn:(id)sender { // 響應(yīng)黃色按鈕}

怎么辦?

Responder Chain 原理講解:手指點(diǎn)擊屏幕,經(jīng)過系統(tǒng)響應(yīng)(之前過程省略不說,文末有參考鏈接),調(diào)用 UIApplication 的 sendEvent: 方法,將 UIEvent 傳給 UIWindow, 通過遞歸調(diào)用 UIView 層級的 hitTest(_:with:) ,結(jié)合 point(inside:with:) 找到 UIEvent 中每一個UITouch 所屬的 UIView(其實(shí)是想找到離觸摸事件點(diǎn)最近的那個 UIView)。這個過程是從 UIView 層級的最頂層往最底層遞歸查詢。同一層級的 UIView,會優(yōu)先深度遍歷界面靠前的 UIView。找到最底層 UIView 后,沿著 Responder Chain 逐步向上傳遞(UIControl 子類默認(rèn)會攔截傳遞)。

解決思路:重寫 ZYYBarrageView 的 hitTest(_:with:) 方法。代碼如下:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { BOOL isPointInsideSubview = [self.redView.layer.presentationLayer hitTest:point]; if (isPointInsideSubview == NO) {  // 如果沒有點(diǎn)擊在移動的 redView 上,返回 nil  // 系統(tǒng)會去遍歷位于 ZYYBarrageView 后面的 UIButton,UIButton 能得到響應(yīng)  return nil; } else {  return [super hitTest:point withEvent:event]; }}

如此,可以完美解決啦~

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對武林網(wǎng)的支持。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鸡泽县| 通州区| 疏附县| 女性| 旌德县| 晋州市| 洛南县| 南漳县| 肇州县| 紫金县| 久治县| 根河市| 桦川县| 正镶白旗| 哈密市| 法库县| 开封市| 宜丰县| 汉中市| 依兰县| 汤原县| 武隆县| 泉州市| 方正县| 两当县| 郴州市| 天津市| 湖北省| 屏边| 涡阳县| 盐边县| 泽普县| 石屏县| 灵石县| 大丰市| 香河县| 古浪县| 茶陵县| 彰化县| 汤原县| 淮安市|