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.
- 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. }