iOS開(kāi)發(fā)之高仿斗魚(yú)tv初探

最近直播比較火尔崔,開(kāi)發(fā)者也相近去模仿一些直播的應(yīng)用,比如喵播褥民,映客等等季春,我也利用閑暇時(shí)間模仿了斗魚(yú),供大家互相學(xué)習(xí)消返,有哪些不足的地方载弄,還請(qǐng)大家多多討論交流。

程序預(yù)覽圖

由于項(xiàng)目需要額外再導(dǎo)入個(gè)框架撵颊,所以不想導(dǎo)入宇攻,想直接查看源碼的,可以通過(guò)百度云下載本項(xiàng)目:https://pan.baidu.com/s/1nv8iubJ

整體的設(shè)計(jì)一覽

  • 在AppDelegate.m中設(shè)置應(yīng)用程序的根控制器為YCTabBarViewController

  • Main文件夾
    這里面包含YCNavgationController和YCTabBarViewController
    (1)倡勇、在YCNavgationController里設(shè)置了導(dǎo)航欄的pop和push手勢(shì)逞刷,也就是去掉了系統(tǒng)自帶的邊緣手勢(shì),換成了全屏的pop手勢(shì)妻熊,具體的實(shí)現(xiàn)可以參考YCNavgationController.m中的代碼夸浅,也可以閱覽這個(gè)博文輕松學(xué)習(xí)之二——iOS利用Runtime自定義控制器POP手勢(shì)動(dòng)畫(huà)
    (2)、在YCTabBarViewController里扔役,主要設(shè)置了4個(gè)主要的控制器帆喇,分別是Home(首頁(yè))、Live(直播)亿胸、Focus(關(guān)注)坯钦、Me(我的),還有另外的兩個(gè)小配置
    ① 設(shè)置哪些頁(yè)面支持自動(dòng)轉(zhuǎn)屏侈玄,目前只設(shè)置了播放的控制器支持

/*
 * 哪些頁(yè)面支持自動(dòng)轉(zhuǎn)屏
 */
 - (BOOL)shouldAutorotate{
    UINavigationController *nav = self.viewControllers[self.selectedIndex];
    if ([nav.topViewController isKindOfClass:[YCLivePlayViewController class]]) {
        return YES;
    }
    return NO;
}

② 設(shè)置控制器所支持的屏幕方向

/**
 *  viewcontroller支持哪些轉(zhuǎn)屏方向
 */
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
    UINavigationController *nav = self.viewControllers[self.selectedIndex];
    if ([nav.topViewController isKindOfClass:[YCLivePlayViewController class]]) {
        YCLivePlayViewController *liveVc = (YCLivePlayViewController *)nav.topViewController;
        // 判斷如果直播控制器點(diǎn)擊了婉刀,鎖定屏幕的話,就禁止豎屏
        if (liveVc.isLock) {
            return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
        }
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
    // 其他頁(yè)面
    return UIInterfaceOrientationMaskPortrait;
}  
  • Home文件夾
    首先介紹一下YZDisplayViewController拗馒,這是一個(gè)包含今日頭條路星、網(wǎng)易新聞等標(biāo)題樣式的方便易用的第三方,更詳細(xì)的使用方法可以先閱讀以下快速集成App中頂部標(biāo)題滾動(dòng)條,或者查看項(xiàng)目的源碼
    在閱讀了YZDisplayViewController之后洋丐,我發(fā)現(xiàn)沒(méi)有和斗魚(yú)一模一樣的樣式呈昔,所以我就改了改代碼,以前的標(biāo)題長(zhǎng)度是根據(jù)文字的多少來(lái)設(shè)置的友绝,改過(guò)之后的支持等長(zhǎng)的標(biāo)題文字堤尾,也就是說(shuō),可以統(tǒng)一設(shè)置標(biāo)題的寬度迁客,而忽略文字的長(zhǎng)度郭宝,下面來(lái)介紹一下
    首先來(lái)介紹一下我額外添加的兩個(gè)屬性customLabelsWidth和customMargin,使用NSNumber的用意是防止我們沒(méi)有設(shè)置寬度和間距的時(shí)候掷漱,它默認(rèn)認(rèn)為我們?cè)O(shè)置了0
/**
 *  自定義的等長(zhǎng)label的寬度
 */
@property (nonatomic,strong) NSNumber *customLabelsWidth;

/**
 *  自定義的titleLabel的間距
 */
@property (nonatomic,strong) NSNumber *customMargin;

下圖做了一層判斷粘室,如果我們自己設(shè)置了寬度和間距,就不會(huì)再去計(jì)算文字的寬度了卜范,也不會(huì)使用默認(rèn)的間距了


設(shè)置標(biāo)簽的寬度和間距

如果自定義了等長(zhǎng)的寬度衔统,也就說(shuō)明標(biāo)題按鈕的寬度差為0

// 獲取兩個(gè)標(biāo)題按鈕寬度差值
- (CGFloat)widthDeltaWithRightLabel:(UILabel *)rightLabel leftLabel:(UILabel *)leftLabel
{
    // 自定義了等長(zhǎng)的寬度
    if (self.customLabelsWidth) {
        return 0;
    }
    
    CGRect titleBoundsR = [rightLabel.text boundingRectWithSize:CGSizeMake(MAXFLOAT, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.titleFont} context:nil];
    
    CGRect titleBoundsL = [leftLabel.text boundingRectWithSize:CGSizeMake(MAXFLOAT, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.titleFont} context:nil];
    
    return titleBoundsR.size.width - titleBoundsL.size.width;
}

設(shè)置下標(biāo)的位置

// 設(shè)置下標(biāo)的位置
- (void)setUpUnderLine:(UILabel *)label {
    // 獲取文字尺寸
    CGRect titleBounds = [label.text boundingRectWithSize:CGSizeMake(MAXFLOAT, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.titleFont} context:nil];
    CGFloat underLineH = _underLineH?_underLineH:YZUnderLineH;
    self.underLine.y = label.height - underLineH;
    self.underLine.height = underLineH;

    // 最開(kāi)始不需要?jiǎng)赢?huà)
#warning 如果自定義了label的寬度,下標(biāo)也和label寬度一樣
    if (self.underLine.x == 0) {
        self.underLine.width = self.customLabelsWidth ? self.customLabelsWidth.floatValue : titleBounds.size.width;
        self.underLine.x = label.x;
        return;
    }
  
    // 點(diǎn)擊時(shí)候需要?jiǎng)赢?huà)
    [UIView animateWithDuration:0.25 animations:^{
        self.underLine.width = self.customLabelsWidth ? self.customLabelsWidth.floatValue : titleBounds.size.width;
        self.underLine.x = label.x;
    }];
}

最后只需要在YCHomeViewController中海雪,寫(xiě)入以下兩行代碼锦爵,即可實(shí)現(xiàn)等長(zhǎng)的標(biāo)題

    self.customLabelsWidth = [NSNumber numberWithFloat:self.view.width / self.childViewControllers.count];
    self.customMargin = [NSNumber numberWithFloat:0.00001]; // 切記如果設(shè)置等長(zhǎng)的話,必須再設(shè)置自定義的margin為一個(gè)很小的值奥裸,但是不能為0

下面來(lái)介紹一下险掀,Home控制器下的四個(gè)子控制器
(1)、YCRecommendViewController(推薦控制器)
輪播采用的一個(gè)第三方SDCycleScrollView
底下的標(biāo)簽一欄湾宙,一個(gè)UIScrollView樟氢,然后添加自定義的UIButton就可以了,至此上面的所有控件共同組成了tableView的tableHeaderView
创倔。
然后就是自定義的YCRecommendCell和自定義的YCRecommendHeaderView嗡害,這個(gè)cell裝著一個(gè)UICollectionView用來(lái)排版所有的房間,也就是說(shuō)畦攘,每一個(gè)cell代表一個(gè)分組,這個(gè)組的headerView就是YCRecommendHeaderView十电,然后這個(gè)cell里有一個(gè)UICollectionView知押,這個(gè)UICollectionView里面就裝著所有的房間,點(diǎn)擊每個(gè)房間就調(diào)用cell的block屬性鹃骂,具體的可以查看源碼
(2)台盯、接下來(lái)的游戲,娛樂(lè)畏线,趣玩和推薦都大同小異静盅,可以閱讀以下源碼

  • Live文件夾
    主要的控制器是YCLiveViewController,這里面的設(shè)置和YCHomeViewController差不多不一樣的就是,多了一個(gè)下拉的view蒿叠,詳細(xì)的內(nèi)容在YCLiveTopView和YCLiveDownView里

  • Focus文件夾
    沒(méi)有什么難的地方明垢,設(shè)置以下未開(kāi)播和直播中,只是搭了搭界面

  • Me文件夾
    目前只是搭了搭“我的”的界面市咽,后續(xù)會(huì)更新這里的內(nèi)容

  • 修改了MJRefresh源代碼
    由于斗魚(yú)官方提供的是一組刷新的圖片痊银,所以如果利用原本的mjrefresh,會(huì)倒是圖片顯示的位置不對(duì)施绎,所以就修改了一下它的源代碼溯革,具體修改的文件是MJRefreshGifHeader.m、MJRefreshStateHeader.h谷醉、MJRefreshStateHeader.m這三個(gè)文件致稀,讀者可以查看這個(gè)三個(gè)文件中的#warning的地方,因此對(duì)于MJRefresh我并沒(méi)有使用cocoapods俱尼,防止有時(shí)需要更新pod時(shí)抖单,把修改過(guò)的MJRefresh給更新了

  • 接下來(lái)介紹一下播放器
    直播的框架,我使用的b站的ijkplayer号显,詳細(xì)的集成方法和使用方法臭猜,可以參考這篇博文iOS中集成ijkplayer視頻直播框架
    對(duì)于直播的彈幕,使用目前iOS比較廣泛應(yīng)用的一個(gè)第三方BarrageRenderer,可以查看它的github源碼學(xué)習(xí)使用彈幕渲染庫(kù)BarrageRenderer

  • YCLivePlayViewController(播放控制器)押蚤,使用時(shí)蔑歌,只需要?jiǎng)?chuàng)建和設(shè)置播放的地址即可

  • YCLodingView,負(fù)責(zé)加載的動(dòng)畫(huà)

  • YCPortraitControlView豎屏下的控制的view揽碘,豎屏下的操作比較少次屠,所以我使用了純代碼的方式,來(lái)創(chuàng)建這個(gè)控制的view

  • YCLandScapeControlView橫屏下控制器的view雳刺,橫屏下的操作比較多劫灶,我就結(jié)合了xib來(lái)完成橫屏的操作

“我要直播”這塊目前還沒(méi)有做,有時(shí)間的話再更新這塊掖桦,不過(guò)大家可以先學(xué)習(xí)一下本昏,讀讀這個(gè)博文快速集成iOS基于RTMP的視頻推流

運(yùn)行項(xiàng)目時(shí),請(qǐng)查看ijkplayer的集成過(guò)程枪汪,然后將打包好的框架涌穆,導(dǎo)入到播放->IJKMediaFramework文件夾下,如果不想自己導(dǎo)入的話雀久,我百度云分享給你們https://pan.baidu.com/s/1o8jdEMA

最后宿稀,附上github地址,歡迎下載查看赖捌,有什么好的意見(jiàn)或者不足也可以找我討論交流https://github.com/ITChong/DouYuTvImitation

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末祝沸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罩锐,老刑警劉巖奉狈,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異唯欣,居然都是意外死亡嘹吨,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)境氢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蟀拷,“玉大人,你說(shuō)我怎么就攤上這事萍聊∥史遥” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵寿桨,是天一觀的道長(zhǎng)此衅。 經(jīng)常有香客問(wèn)我,道長(zhǎng)亭螟,這世上最難降的妖魔是什么挡鞍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮预烙,結(jié)果婚禮上墨微,老公的妹妹穿的比我還像新娘。我一直安慰自己扁掸,他們只是感情好翘县,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著谴分,像睡著了一般锈麸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牺蹄,一...
    開(kāi)封第一講書(shū)人閱讀 49,985評(píng)論 1 291
  • 那天忘伞,我揣著相機(jī)與錄音,去河邊找鬼沙兰。 笑死虑省,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的僧凰。 我是一名探鬼主播,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼熟丸,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼训措!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绩鸣,失蹤者是張志新(化名)和其女友劉穎怀大,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體呀闻,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡化借,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捡多。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓖康。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖垒手,靈堂內(nèi)的尸體忽然破棺而出蒜焊,到底是詐尸還是另有隱情,我是刑警寧澤科贬,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布泳梆,位于F島的核電站,受9級(jí)特大地震影響榜掌,放射性物質(zhì)發(fā)生泄漏优妙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一憎账、第九天 我趴在偏房一處隱蔽的房頂上張望套硼。 院中可真熱鬧,春花似錦鼠哥、人聲如沸熟菲。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抄罕。三九已至,卻和暖如春于颖,著一層夾襖步出監(jiān)牢的瞬間呆贿,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工森渐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留做入,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓同衣,卻偏偏與公主長(zhǎng)得像竟块,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耐齐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)浪秘、插件蒋情、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,066評(píng)論 4 62
  • Swift版本點(diǎn)擊這里歡迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh閱讀 25,339評(píng)論 7 249
  • “消防局月初來(lái)通知說(shuō)嚴(yán)禁野外用火」瞪常”道士沒(méi)法招雷很郁悶河劝。“誰(shuí)知道它算幾級(jí)保護(hù)尝胆!”因?yàn)榭乘檠F被環(huán)保局罰款的和尚這回...
    洞庭府君閱讀 600評(píng)論 0 6
  • 有一種愛(ài)是只要她好含衔,我愿意離她遠(yuǎn)遠(yuǎn)的煎娇,就當(dāng)從沒(méi)有在她生命中出現(xiàn)過(guò)一樣。 在第六次穿越后贪染,一切好像算是比較正常的缓呛,除...
    親哥拜閱讀 682評(píng)論 0 4
  • 舉例來(lái)說(shuō)就是女人剛開(kāi)始和你聊天的狀態(tài):哦,呵呵杭隙、是么哟绊、這樣啊、 我覺(jué)得也是痰憎、好吧票髓、我知道了。 不管女人回應(yīng)的態(tài)度如...
    CNBLUEone閱讀 954評(píng)論 0 1