源码

首页 » 归档 » 源码 » 源码分享:高仿喜马拉雅FM-ios学习从入门到精通尽在姬长信

源码分享:高仿喜马拉雅FM-ios学习从入门到精通尽在姬长信

分享最热门的ios资讯

项目地址github:https://github.com/Eastwu5788/XMLYFM 如果您觉得不错,记得给一个star

最面目目样用空闲时间高仿了一下喜马拉雅FM这款APP,目前主要完成了发现栏目中的推荐页面。

效果演示

分析

+发现tab中有五个小分类,分别对应五个页面,所有在“发现”的控制器中使用了UIPageViewController来控制五个子控制器。
+从Charles抓出来的接口来看,“推荐”页面一共调用了三个接口,分别请求了推荐、热门、直播的内容,所以在这里选择了Reactivecocoa来实现接口的并发访问

- (void)refreshDataSource {       

    @weakify(self);
    RACSignal *signalRecommend = [RACSignal createSignal:^RACDisposable *(id subscriber) {
        @strongify(self);
        [self requestRecommendList:^{
            [subscriber sendNext:nil];
        }];
        return nil;
    }];    

    RACSignal *signalHotAndGuess = [RACSignal createSignal:^RACDisposable *(id subscriber) {
        @strongify(self);
        [self requestHotAndGuessList:^{
            [subscriber sendNext:nil];
        }];
        return nil;
    }];

    RACSignal *signalLiving = [RACSignal createSignal:^RACDisposable *(id subscriber) {
        @strongify(self);
        [self requestLiving:^{
            [subscriber sendNext:nil];
        }];
        return nil;
    }];

    [[RACSignal combineLatest:@[signalRecommend,signalHotAndGuess,signalLiving]] subscribeNext:^(id x) {
        @strongify(self);
        [(RACSubject *)self.updateContentSignal sendNext:nil];
    }];
}



文章转自 耐心_朱迪的简书

+在“推荐”页面中有几个轮播图,仔细视察会发现它的轮播图一直想左转换,所以这里的轮播图片需要做一下特殊处理。以实现无限轮播的效果

- (void)setModel:(XMLYFindFocusImagesModel *)model  {      
    _model = model;    
    [self.adverScrollView removeAllSubViews];    
    self.adverScrollView.contentSize = CGSizeMake(kScreenWidth * _model.list.count, 150);     
    //1.向scrollView中增加UIImageView的时候,需要在最后一张图片后面将第一张图片添加上去    
    for(NSInteger index = 0; index <= _model.list.count; index++)   {      
        //2.如果是最后一张图片,则放置第一张图片
        XMLYFindFocusImageDetailModel \*detail = index == _model.list.count ? _model.list.firstObject : [_model.list objectAtIndex:index];
        UIImageView \*imageView = [[UIImageView alloc] init];
        imageView.frame = CGRectMake(kScreenWidth \* index, 0, kScreenWidth, 150);
        [imageView yy_setImageWithURL:[NSURL URLWithString:detail.pic] options:YYWebImageOptionSetImageWithFadeAnimation];
        [self.adverScrollView addSubview:imageView];
    }
}

在轮播图转动动画结束后需要做一下判断,如果当前转动到了最后一张图片,则立即将scrollView的偏移调整到初始位置,这样一个无限轮播就完成了。

- (void)scrollViewDidScroll:(UIScrollView \*)scrollView {   
    NSInteger curPage = self.adverScrollView.contentOffset.x / kScreenWidth;    
    if(curPage == self.model.list.count) {    
        [self.adverScrollView setContentOffset:CGPointMake(0, 0) animated:NO];    
      }
}

在有轮播图的地方肯定少不了定时器,如果将定时器直接放在cell中,就会因为cell的复用导致定时器出现问题,所有一般是将定时器放在控制器中。但是这样的话也带来一个问题,就是由于定时器的存在,如果要求定时器的生命周期和控制器相同(也就是在控制器dealloc的时候才取消定时器).这样的控制器是无法调用dealloc的,会造成控制器虽然已经退出但是定时器依然在正常工作。所以这里专门为控制器设计了一个定时器的单例资助类,这样的话就可以在dealloc中去销毁所有的定时器。

@interface XMLYFindRecommendHelper : NSObject    
#pragma mark - Common    
//生成资助类单例
+ (instancetype)helper;    

//销毁所有的定时器    
- (void)destoryAllTimer;

#pragma mark - Live    

//  开启为直播设置的定时器      
- (void)startLiveTimer;    

//销毁直播的定时器    
- (void)destoryLiveTimer;    

#pragma mark - Header    

//开启头部的定时器    
- (void)startHeadTimer;    

//销毁头部的定时器    
- (void)destoryHeaderTimer;    
@end

在广播页面中,有一个凭据当前时间显示差别的问候语的小功能。比如现在是早上6点钟,应该显示“早安*北京”。这里就需要用到NSDateFormatter,但是NSDateFormatter的对照消耗性能,所以我专门写了一个XMLYTimeHelper类来管理所有的时间转换操作。在这个类中对NSDateFormatter做了缓存处理,并使用dispatch_semaphore_t保证了线程宁静。

//凭据字符串生成相应的NSDateFormatter,比如"yyyy-MM-dd HH:mm:ss"
static force_inline NSDateFormatter *XMLYDataCreateFormatter(NSString *string) {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
    formatter.dateFormat = string;
    return formatter;
}

//用户直接调用此要领,传入"yyyy-MM-dd HH:mm:ss"这样的字符串生成NSDateFormatter
static force_inline NSDateFormatter *XMLYDateFormatter(NSString *string) {
    //1.检查输入的厚利性
    if(!string || ![string isKindOfClass:[NSString class]] || string.length == 0) return nil;
   //2.初始化单例参数
    static CFMutableDictionaryRef cache;
    static dispatch_semaphore_t lock;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        cache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        lock = dispatch_semaphore_create(1);
    });

    //3.加锁
    dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
    //4.查询当前字符串是否已经存在相应的NSDateformatter
    NSDateFormatter *formatter = CFDictionaryGetValue(cache, (__bridge const void *)(string));
   //5.解锁
    dispatch_semaphore_signal(lock);

   //6.如果缓存中没有,则需要重面目目样生成
    if(!formatter) {
        formatter = XMLYDataCreateFormatter(string);
        //7.重面目目样生成成功,存入缓存
        if(formatter) {
            dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
            CFDictionarySetValue(cache, (__bridge const void *)(string), (__bridge const void *)(formatter));
            dispatch_semaphore_signal(lock);
        }
    }
    return formatter;
}

文章转自 East_wu的简书
用意志战胜身体的惰性!

(0)

本文由 姬長信 创作,文章地址:https://blog.isoyu.com/archives/1166.html
采用知识共享署名4.0 国际许可协议进行许可。除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为:9 月 9, 2016 at 03:59 下午

关键词:

热评文章

发表回复

[必填]

我是人?

提交后请等待三秒以免造成未提交成功和重复