Late at night - the world was so sexy

Keywords: iOS JSON Javascript network Attribute

Late at night - the world was so sexy

Project brief introduction

  • The project is written in pure code and the project cycle is 14 days.
  • APP is divided into three big modules
    • Night module
    • Select module
    • Thematic module

Project Display Analysis

  • Overall structure

  • Trilateral wheels used

Project timeline

February 7, 2017

  • Network Tool Class Writing
#import <Foundation/Foundation.h>
@interface BaseNetManager : NSObject
//GET
+ (id)GET:(NSString *)path param:(NSDictionary *)param completionHandler:(void(^)(id obj, NSError *error))completionHandler;
//POST
+ (id)POST:(NSString *)path param:(NSDictionary *)param completionHandler:(void(^)(id obj, NSError *error))completionHandler;
@end
//GET 
@implementation BaseNetManager
+ (id)GET:(NSString *)path param:(NSDictionary *)param completionHandler:(void (^)(id, NSError *))completionHandler
{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer.timeoutInterval = 10;
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", @"application/json", @"text/json", @"text/javascript", @"text/plain", nil];
    return [manager GET:path parameters:param progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"%@", task.currentRequest.URL.absoluteString);
        !completionHandler ?: completionHandler(responseObject, nil);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"%@", error);
    }];
}

//POST
+ (id)POST:(NSString *)path param:(NSDictionary *)param completionHandler:(void (^)(id, NSError *))completionHandler
{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer.timeoutInterval = 15;
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", @"application/json", @"text/json", @"text/javascript", @"text/plain", nil];
    return [manager POST:path parameters:param progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"%@", task.currentRequest.URL.absoluteString);
        !completionHandler ?: completionHandler(responseObject, nil);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"%@", error);
        !completionHandler ?: completionHandler(nil, error);
    }];
}
@end

February 8, 2017

#import "YGTabBarController.h"
#import "YGHomeController.h"
#import "YGEssenceController.h"
#import "YGListController.h"
#import "YGListFlowLayout.h"
#import "YGPageController.h"
@interface YGTabBarController ()

@end

@implementation YGTabBarController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self allPropertySetup];
    [self setupAllControllers];
}

#pragma mark - global attribute
- (void)allPropertySetup
{
    [UITabBar appearance].tintColor = YGRGBColor(67, 67, 67);
    [UINavigationBar appearance].tintColor = YGRGBColor(67, 67, 67);
    [[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: YGRGBColor(67, 67, 67)} forState:UIControlStateSelected];
    
    [UIImageView appearance].contentMode = UIViewContentModeScaleAspectFill;
    [UIImageView appearance].clipsToBounds = YES;
    [UICollectionView appearance].backgroundColor = YGBgColor;
    [UIImageView appearance].contentMode = UIViewContentModeScaleAspectFill;
    [UIImageView appearance].clipsToBounds = YES;
}

#pragma mark - Create all tabBar subcontrollers
- (void)setupAllControllers
{
    YGPageController *pageVC = [[YGPageController alloc] init];
    pageVC.tabBarItem.image = @"nav_ic_home_default".yg_image;
    pageVC.tabBarItem.selectedImage = @"nav_ic_home_selected".yg_image;
    pageVC.title = @"To night";
    UINavigationController *homeNavi = [[UINavigationController alloc] initWithRootViewController:pageVC];
    
    YGEssenceController *essenceVC = [[YGEssenceController alloc] initWithStyle:UITableViewStylePlain];
    essenceVC.title = @"Selected";
    essenceVC.tabBarItem.image = @"tab_btn_list_default".yg_image;
    essenceVC.tabBarItem.selectedImage = @"tab_btn_list_select".yg_image;
    UINavigationController *essenceNavi = [[UINavigationController alloc] initWithRootViewController:essenceVC];
    
    YGListController *listVC = [[YGListController alloc] initWithCollectionViewLayout:[[YGListFlowLayout alloc] init]];
    listVC.title = @"special";
    listVC.tabBarItem.image = @"nav_ic_columns_default".yg_image;
    listVC.tabBarItem.selectedImage = @"nav_ic_columns_selected".yg_image;
    UINavigationController *listNavi = [[UINavigationController alloc] initWithRootViewController:listVC];
    
    self.viewControllers = @[homeNavi, essenceNavi, listNavi];
}


#pragma mark - Turn off the device to rotate automatically, then manually monitor the direction of rotation to rotate the avplayerView
-(BOOL)shouldAutorotate{
    return NO;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

9 February 2017 - 13 February 2017

  • To night information, I start with a little simple page -- Essence module.

  • TableViewController as a whole, which is divided into three types of Cell s
    • Layout layout with masonry as a whole
    • The interface is relatively simple as a whole, in which Cell is highly adaptive, and I use the UITableView-FDTemplateLayoutCell For high performance adaptive height, the former Baidu forkingdog team and now the iOS God Sunnyxx released the high performance Cell automatic height computing framework.
//High Performance Computing Line Height
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    YGEssenceResponseFeedsItem *feedsItem = self.essenceArr[indexPath.section];
    if (feedsItem.type == 1) {
        return [tableView fd_heightForCellWithIdentifier:@"YGEssenceCommomCell" configuration:^(YGEssenceCommomCell *cell) {
            
            cell.iconIV.imageURL = feedsItem.image.yg_URL;
        }];
    }
    if (feedsItem.type == 0) {
        return [tableView fd_heightForCellWithIdentifier:@"YGEssenceImageCell" configuration:^(YGEssenceImageCell *cell) {
            [cell.iconIV setImageWithURL:feedsItem.image.yg_URL options:YYWebImageOptionIgnoreAnimatedImage];
        }];
    }
    
    return [tableView fd_heightForCellWithIdentifier:@"YGEssenceBigCell" configuration:^(YGEssenceBigCell *cell) {
        cell.titleLB.text = feedsItem.post.title;
        cell.detailLB.text = feedsItem.post.des;
        [cell.iconIV setImageWithURL:feedsItem.image.yg_URL options:YYWebImageOptionIgnoreAnimatedImage];
    }];
  
}
  • The essence module is mainly information and information, which uses UIWebView to display, and there is a small animation which withdraws from the button.
#pragma mark - create suspension button
- (void)creatSuspendButton
{
    self.suspendBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.suspendBtn setBackgroundImage:[UIImage imageNamed:@"homeBackButton"] forState:UIControlStateNormal];
    self.suspendBtn.frame = CGRectMake(0, 0, 54, 54);
    [self.suspendBtn addTarget:self action:@selector(clickSuspendButton) forControlEvents:UIControlEventTouchUpInside];
    //Create the window of the suspension button
    self.buttonWin = [[UIView alloc] initWithFrame:CGRectMake(25, YGScreenH - 60, 54, 54)];
    self.buttonWin.backgroundColor = [UIColor clearColor];
    //Show buttonWin
    [self.view addSubview:self.buttonWin];
    [self.buttonWin addSubview:self.suspendBtn];
    
    
}
//Click on the suspension button
- (void)clickSuspendButton
{
    self.buttonWin.hidden = YES;
    self.buttonWin = nil;
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - viewWillAppear
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden = YES;
}
#pragma mark - viewViewDisappear
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    self.navigationController.navigationBarHidden = NO;
}
//Button hiding
#pragma mark - <UIScrollViewDelegate>
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    
    if (scrollView.contentOffset.y > _offsetY + 1) {
        [self suspensionWithAlpha:0];
    }
    else if (scrollView.contentOffset.y < _offsetY)
    {
        [self suspensionWithAlpha:1];
    }
}

//Stop scrolling calls
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    _offsetY = scrollView.contentOffset.y;
}

//Setting Transparency of Suspension Button
- (void)suspensionWithAlpha:(CGFloat)alpha
{
    [UIView animateWithDuration:0.3 animations:^{
        [self.buttonWin setAlpha:alpha];
    }];
}
  • Specific examples

February 14, 2017 - February 15, 2017

  • Column module structure

  • Thematic modules are divided into three jumps
    • The first UICollection View Controller
    • The second interface UITableViewController
    • The third interface plays UIViewController
  • Topic Modules and Lists Detailed Overall masonry Layout
  • I used HcdCachePlayer to play the list in detail.
    • HcdCachePlayer has good integration for overall playback and caching
#import "YGListDetailMovieController.h"

@interface YGListDetailMovieController ()
{
    //player
    HcdCacheVideoPlayer *_play;
    
}
/** background */
@property(nonatomic, strong) UIImageView *bgView;
/** Head portrait */
@property(nonatomic, strong) UIImageView *headView;
/** detailed */
@property(nonatomic, strong) UILabel *detailLb;
/** Film introduction */
@property(nonatomic, strong) UILabel *constLabel;
/** Play button */
@property(nonatomic, strong) UIButton *playBtn;
// Calculate properties, screen size
@property (nonatomic, assign) CGSize screenSize;

@end

@implementation YGListDetailMovieController



- (instancetype)initWithBgImageView:(NSString *)bgImageView titleView:(NSString *)titleView detailLabel:(NSString *)titleLabel url:(NSString *)url;
{
    self = [super init];
    if (self) {
        self.titleView = titleView;
        self.bgImageView = bgImageView;
        self.detailLabel = titleLabel;
        self.url = url;
        self.hidesBottomBarWhenPushed = YES;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [self configUI];
}
//Configure Play Interface
- (void)configUI
{
    self.bgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, YGScreenW, YGScreenH)];
    self.bgView.userInteractionEnabled = YES;
    [self.bgView setImageURL:self.bgImageView.yg_URL];
    [self.view addSubview:self.bgView];
    
    self.headView = [[UIImageView alloc] init];
    [self.headView setImageURL:self.titleView.yg_URL];
    self.headView.userInteractionEnabled = YES;
    [self.bgView addSubview:self.headView];
    [self.headView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.offset(0);
        make.top.offset(64);
        CGFloat scale = 27 / 32.0;
        make.height.mas_equalTo(self.headView.mas_width).multipliedBy(scale);
    }];
    
    self.constLabel = [[UILabel alloc] init];
    self.constLabel.font = [UIFont boldSystemFontOfSize:18];
    self.constLabel.textColor = [UIColor whiteColor];
    self.constLabel.text = @"Film introduction:";
    [self.bgView addSubview:self.constLabel];
    [self.constLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.offset(10);
        make.top.mas_equalTo(self.headView.mas_bottom).offset(10);
    }];
    
    self.detailLb = [[UILabel alloc] init];
    self.detailLb.text = self.detailLabel;
    self.detailLb.textColor = [UIColor whiteColor];
    self.detailLb.numberOfLines = 0;
    [self.bgView addSubview:self.detailLb];
    [self.detailLb mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.offset(10);
        make.right.offset(-10);
        make.top.mas_equalTo(self.constLabel.mas_bottom).offset(10);
    }];
    
    self.playBtn = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.playBtn setImage:[UIImage imageNamed:@"play_button"] forState:UIControlStateNormal];
    [self.headView addSubview:self.playBtn];
    [self.playBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.center.offset(0);
        make.size.mas_equalTo(60);
    }];
    [self.playBtn addTarget:self action:@selector(playMovie) forControlEvents:UIControlEventTouchUpInside];
}

//Play video
- (void)playMovie
{
    self.headView.hidden = YES;
    //    self.constLabel.hidden = YES;
    //    self.detailLb.hidden = YES;
    //Click to create a playback interface
    _play = [[HcdCacheVideoPlayer alloc] init];
    UIView *videoView = [[UIView alloc] initWithFrame:CGRectMake(0, 64, YGScreenW, YGScreenW * 27 / 32.0)];
    
    [self.view addSubview:videoView];
    //play
    [_play playWithUrl:self.url.yg_URL showView:videoView andSuperView:self.view withCache:YES];
    NSLog(@"%@", NSHomeDirectory());
    
    NSLog(@"%f", [HcdCacheVideoPlayer allVideoCacheSize]);

    
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark-life cycle method
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [_play stop];
#warning WAIT TODO: Clear all caches here first
    [HcdCacheVideoPlayer clearAllVideoCache];
    
}

- (CGSize)screenSize
{
    return [UIScreen mainScreen].bounds.size;
}

@end
  • Video display

February 16, 2017

  • Start the Night Module Writing
  • episode
    • When the Model layer and View layer are all written and the Controller layer is all written, the video is just playback, video encryption is found and all spam advertisements are displayed. I was busy all night. At 3:35 a.m.

February 17 - 19, 2017

  • There are two kinds of Cell s in the "going" module at night

    • A Cell for Information Display
    • A Cell for Video Display

  • Night Module

  • ” Night Module
    • The first interface is Tableview Controller
  • Click in "More Topics" for UICollection View Controller
  • Click on a detailed list of topics with a stretch image at the top and a tableview below.

  • More topics include topics showing pictures.
    • I use the MW PhotoBrowser framework.

February 20, 2017

  • Ending

Holistic analysis

  • The project mainly focuses on displaying information, news, film and television clips.
  • The project structure is simple and the overall tone is gray and black.
  • No xib or sb is involved in the whole project

Combing the details of the project

  • Head infinite rotation
  • Use iCarousel tripartite architecture.
    • I was thinking about using one I wrote. Unlimited carousel Framework, but I have no other encapsulation, just to achieve high-performance rotation. So I used iCarousel tripartite architecture.
#pragma mark - <ic Delegate>
- (NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
    return self.loopArr.count;
}

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
{
    if (!view) {
        view = [[UIView alloc] initWithFrame:carousel.bounds];
        UIImageView *iconIV = [[UIImageView alloc] init];
        [view addSubview:iconIV];
        [iconIV mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.left.right.offset(0);
            CGFloat scale = 38 / 64.0;
            make.height.mas_equalTo(iconIV.mas_width).multipliedBy(scale);
        }];
        iconIV.tag = 100;
    }
    YYAnimatedImageView *iconIV = [view viewWithTag:100];
    [iconIV setImageWithURL:[NSURL URLWithString:self.loopArr[index]] options:YYWebImageOptionIgnoreAnimatedImage];
    return view;
}
//It's only when things change that we come to this approach.
- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel
{
    self.titleLb.text = self.bannersArr[carousel.currentItemIndex].post.title;
    self.pc.currentPage = carousel.currentItemIndex;
}

- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index
{
        YGEssenceWebController *webVC = [[YGEssenceWebController alloc] initWithAppView:self.bannersArr[index].post.appview];
        [self.navigationController pushViewController:webVC animated:YES];
}

- (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
{
    if (option == iCarouselOptionWrap) {
        value = YES;
    }
    return value;
}
  • Horizontal rolling of the head of the "Night" module
    • Using a tripartite control of WMPageController
@interface YGPageController ()

@end

@implementation YGPageController

//Initialization method
- (instancetype)init
{
    if (self = [super init]) {
        self.menuBGColor = YGRGBColor(249, 249, 249);
        
        self.menuViewStyle = WMMenuViewStyleLine;
        self.menuViewLayoutMode = WMMenuViewLayoutModeCenter;
        self.titleSizeNormal = 20;
        self.titleSizeSelected = self.titleSizeNormal;
        
        self.titleColorSelected = self.titleColorNormal;
        self.automaticallyCalculatesItemWidths = YES; //Automatic Width Calculations Based on Topic Content
        self.itemMargin = 30; //Topic spacing
        self.menuHeight = 44;
        self.showOnNavigationBar = YES;
    }
    return self;
}

- (NSArray<NSString *> *)titles
{
    return @[@"to", @"night"];
}


- (NSInteger)numbersOfChildControllersInPageController:(WMPageController *)pageController
{
    return self.titles.count;
}

- (UIViewController *)pageController:(WMPageController *)pageController viewControllerAtIndex:(NSInteger)index
{
    if (index == 0) {
        YGHomeController *homeVC = [[YGHomeController alloc] init];
        return homeVC;
    }
    YGCategoryController *cateVC = [[YGCategoryController alloc] init];
    return cateVC;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

YG - sunlight

Work in spare time starts at 11 p.m. and ends at about 4 a.m. on average. Work on your own business at 9 a.m.
If you think it's good, please give me a small one.

GitHub address
Blog Garden Address
Evening Project Address

Posted by Squirrel86 on Mon, 01 Apr 2019 16:54:30 -0700