Commit 59cdac5b by MissYasiky

添加云课堂 demo iOS 代码到项目中

parent d9eec957
//
// FTPageController.h
// FTPageController
//
// Created by ftao on 04/01/2018.
// Copyright © 2018 easefun. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol FTPageControllerDelegate;
/**
自定义分页控制器
*/
@interface FTPageController : UIViewController
@property (nonatomic, weak) id<FTPageControllerDelegate> delegate;
@property (nonatomic, assign, readonly) CGFloat barHeight;
@property (nonatomic, strong, readonly) NSMutableArray *titles;
@property (nonatomic, strong, readonly) NSMutableArray *controllers;
@property (nonatomic, strong, readonly) UIView *touchLineView;
@property (nonatomic, assign) BOOL circulation;
/**
通过标题及其控制器初始化分页控制器
@param titles 子控制器标题
@param controllers 子控制器
@return 分页控制
*/
- (instancetype)initWithTitles:(NSArray<NSString *> *)titles controllers:(NSArray<UIViewController *> *)controllers barHeight:(CGFloat)barHeight touchHeight:(CGFloat)touchHeight;
/**
新增页
@param title 页标题
@param controller 页控制器
*/
- (void)addPageWithTitle:(NSString *)title controller:(UIViewController *)controller;
/**
插入页在指定位置
@param title 页标题
@param controller 页控制器
@param index 位置(大于最大数量时,则插入至最后)
*/
- (void)insertPageWithTitle:(NSString *)title controller:(UIViewController *)controller atIndex:(NSUInteger)index;
/**
移除页控制器
@param index 位置
*/
- (void)removePageAtIndex:(NSUInteger)index;
/// 改变大小
- (void)changeFrame;
/// 是否圆角
- (void)cornerRadius:(BOOL)flag;
@end
@protocol FTPageControllerDelegate <NSObject>
- (BOOL)canMoveChatroom:(FTPageController *)pageController;
- (void)moveChatroom:(FTPageController *)pageController toPointY:(CGFloat)pointY;
- (void)moveChatroom:(FTPageController *)pageController;
@end
//
// FTTitleViewCell.h
// FTPageController
//
// Created by ftao on 04/01/2018.
// Copyright © 2018 easefun. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface FTTitleViewCell : UICollectionViewCell
@property (nonatomic, assign) BOOL clicked;
@property (strong, nonatomic) UILabel *titleLabel;
@property (strong, nonatomic) UIView *indicatorView;
@end
//
// FTTitleViewCell.m
// FTPageController
//
// Created by ftao on 04/01/2018.
// Copyright © 2018 easefun. All rights reserved.
//
#import "FTTitleViewCell.h"
@implementation FTTitleViewCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
CGFloat width = 100.0;
CGFloat height = 44.0;
self.frame = CGRectMake(frame.origin.x, frame.origin.y, width, height);
_titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, height)];
_titleLabel.textColor = [UIColor darkGrayColor];
_titleLabel.font = [UIFont systemFontOfSize:16];
_titleLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:_titleLabel];
_indicatorView = [[UIView alloc] initWithFrame:CGRectMake(34, 41, 32, 3)];
_indicatorView.backgroundColor = [UIColor colorWithRed:0x21/255.0 green:0x96/255.0 blue:0xf3/255.0 alpha:1.0];
[self addSubview:_indicatorView];
_indicatorView.hidden = YES;
}
return self;
}
- (void)setClicked:(BOOL)clicked {
_clicked = clicked;
_indicatorView.hidden = !clicked;
_titleLabel.textColor = clicked ? [UIColor colorWithRed:33/255.0 green:150/255.0 blue:243/255.0 alpha:1.0] : [UIColor darkGrayColor];
}
@end
Copyright (c) 2011-2017 Charles Powell
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
\ No newline at end of file
//
// PLVCameraViewController.h
// zPin_Pro
//
// Created by zykhbl on 2017/12/17.
// Copyright © 2017年 zykhbl. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol PLVCameraViewControllerDelegate;
@interface PLVCameraViewController : UIViewController
@property (nonatomic, weak) id<PLVCameraViewControllerDelegate> delegate;
@end
@protocol PLVCameraViewControllerDelegate <NSObject>
- (void)cameraViewController:(PLVCameraViewController *)cameraVC uploadImage:(UIImage *)uploadImage;
- (void)dismissCameraViewController:(PLVCameraViewController*)cameraVC;
@end
//
// PLVCameraViewController.m
// zPin_Pro
//
// Created by zykhbl on 2017/12/17.
// Copyright © 2017年 zykhbl. All rights reserved.
//
#import "PLVCameraViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "SDWebImageDecoder.h"
#define WIDTH [[UIScreen mainScreen] bounds].size.width
#define HEIGHT [[UIScreen mainScreen] bounds].size.height
@interface PLVCameraViewController ()
@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic, strong) AVCaptureDevice *device;
@property (nonatomic, strong) AVCaptureDeviceInput *videoInput;
@property (nonatomic, strong) AVCaptureStillImageOutput *stillImageOutput;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *preLayer;
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIButton *exitBtn;
@property (nonatomic, strong) UIButton *switchCameraBtn;
@property (nonatomic, strong) UIButton *shootBtn;
@property (nonatomic, strong) UIButton *cancelBtn;
@property (nonatomic, strong) UIButton *sendBtn;
@property (nonatomic, strong) UIImage *selectedImage;
@end
@implementation PLVCameraViewController
#pragma mark - life cycle
- (void)viewDidLoad {
[super viewDidLoad];
self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[self.device lockForConfiguration:nil];
if (self.device.position == AVCaptureDevicePositionFront || self.device.position == AVCaptureDevicePositionUnspecified) {
if ([self.device isFlashModeSupported:AVCaptureFlashModeOff]) {
[self.device setFlashMode:AVCaptureFlashModeOff];
} else if ([self.device isFlashModeSupported:AVCaptureFlashModeOn]) {
[self.device setFlashMode:AVCaptureFlashModeOn];
} else if ([self.device isFlashModeSupported:AVCaptureFlashModeOn]) {
[self.device setFlashMode:AVCaptureFlashModeAuto];
}
} else if ([self.device isFlashModeSupported:AVCaptureFlashModeAuto]) {
[self.device setFlashMode:AVCaptureFlashModeAuto];
}
[self.device unlockForConfiguration];
self.session = [[AVCaptureSession alloc] init];
self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:self.device error:nil];
self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
[self.stillImageOutput setOutputSettings:@{AVVideoCodecKey:AVVideoCodecJPEG}];
if ([self.session canAddInput:self.videoInput]) {
[self.session addInput:self.videoInput];
}
if ([self.session canAddOutput:self.stillImageOutput]) {
[self.session addOutput:self.stillImageOutput];
}
[self.session startRunning];
self.preLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
[self.preLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
self.preLayer.frame = CGRectMake(0.0, 0.0, WIDTH, HEIGHT);
[self.view.layer addSublayer:self.preLayer];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, WIDTH, HEIGHT)];
self.imageView.hidden = YES;
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
[self.view addSubview:self.imageView];
CGFloat y = 30.0;
if (@available(iOS 11.0, *)) {
y += self.view.safeAreaLayoutGuide.layoutFrame.origin.y;
}
self.exitBtn = [self createButton:@"plv_shoot_close.png" frame:CGRectMake(20.0, y, 44.0, 44.0) action:@selector(exitAction:)];
self.switchCameraBtn = [self createButton:@"plv_shoot_switchCamera.png" frame:CGRectMake(WIDTH - 50.0, y, 44.0, 44.0) action:@selector(switchCameraAction:)];
self.shootBtn = [self createButton:@"plv_btn_shoot.png" frame:CGRectMake(WIDTH * 0.5 - 37.0, HEIGHT - 117.0, 74.0, 74.0) action:@selector(shootAction:)];
self.cancelBtn = [self createButton:@"plv_shoot_cancel.png" frame:self.shootBtn.frame action:@selector(cancelAction:)];
self.cancelBtn.hidden = YES;
self.sendBtn = [self createButton:@"plv_shoot_send.png" frame:self.shootBtn.frame action:@selector(sendAction:)];
self.sendBtn.hidden = YES;
}
- (void)dealloc {
[self.session stopRunning];
}
#pragma mark - Action
- (IBAction)exitAction:(UIButton *)sender {
[self dismissCameraViewController];
}
- (IBAction)switchCameraAction:(UIButton *)sender {
self.switchCameraBtn.selected = !self.switchCameraBtn.selected;
AVCaptureDevicePosition direction = AVCaptureDevicePositionBack;
if (self.switchCameraBtn.selected) {
direction = AVCaptureDevicePositionFront;
}
for (AVCaptureDevice *d in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
if ([d position] == direction) {
[self.preLayer.session beginConfiguration];
for (AVCaptureInput *oldInput in self.preLayer.session.inputs) {
[self.preLayer.session removeInput:oldInput];
}
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:d error:nil];
[self.preLayer.session addInput:input];
[self.preLayer.session commitConfiguration];
break;
}
}
}
- (IBAction)shootAction:(UIButton *)sender {
self.exitBtn.hidden = YES;
self.shootBtn.hidden = YES;
AVCaptureConnection *connection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
if (!connection) {
return;
}
__weak typeof(self) weakSelf = self;
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef sampleBuffer, NSError *error) {
if (!error) {
NSData *jpegData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:sampleBuffer];
weakSelf.selectedImage = [UIImage decodedScaleImage:[UIImage imageWithData:jpegData]];
weakSelf.imageView.image = weakSelf.selectedImage;
[weakSelf switchView:YES];
} else {
NSLog(@"%@", [error localizedDescription]);
}
}];
}
- (IBAction)cancelAction:(UIButton *)sender {
[self switchView:NO];
}
- (IBAction)sendAction:(UIButton *)sender {
if (self.delegate && [self.delegate respondsToSelector:@selector(cameraViewController:uploadImage:)]) {
[self.delegate cameraViewController:self uploadImage:self.selectedImage];
}
[self dismissCameraViewController];
}
#pragma mark - view controls
- (BOOL)shouldAutorotate {
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
#pragma mark - private
- (UIButton *)createButton:(NSString *)normalImage frame:(CGRect)frame action:(SEL)action {
UIButton *btn = [[UIButton alloc] initWithFrame:frame];
[btn setBackgroundImage:[UIImage imageNamed:normalImage] forState:UIControlStateNormal];
[btn addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
return btn;
}
- (void)switchView:(BOOL)flag {
self.preLayer.hidden = flag;
self.exitBtn.hidden = flag;
self.switchCameraBtn.hidden = flag;
if (flag) {
self.imageView.hidden = !flag;
self.shootBtn.hidden = flag;
self.cancelBtn.hidden = !flag;
self.sendBtn.hidden = !flag;
}
__weak typeof(self) weakSelf = self;
[UIView animateWithDuration:0.3 animations:^{
if (flag) {
weakSelf.cancelBtn.frame = CGRectMake(WIDTH * 0.5 - 134.0, HEIGHT -117.0, 74.0, 74.0);
weakSelf.sendBtn.frame = CGRectMake(WIDTH * 0.5 + 60.0, HEIGHT -117.0, 74.0, 74.0);
} else {
weakSelf.imageView.alpha = 0.0;
weakSelf.cancelBtn.frame = weakSelf.shootBtn.frame;
weakSelf.sendBtn.frame = weakSelf.shootBtn.frame;
}
} completion:^(BOOL finished) {
weakSelf.imageView.alpha = 1.0;
if (!flag) {
weakSelf.imageView.hidden = !flag;
weakSelf.shootBtn.hidden = flag;
weakSelf.cancelBtn.hidden = !flag;
weakSelf.sendBtn.hidden = !flag;
}
}];
}
- (void)dismissCameraViewController {
if (self.delegate && [self.delegate respondsToSelector:@selector(dismissCameraViewController:)]) {
[self.delegate dismissCameraViewController:self];
}
}
@end
//
// ZAlbumsViewController.h
// zPic
//
// Created by zykhbl on 2017/7/22.
// Copyright © 2017年 zykhbl. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "ZPicDefine.h"
#import "ZAlbumInfo.h"
@protocol ZAlbumsViewControllerDelegate;
@interface ZAlbumsViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, assign) id<ZAlbumsViewControllerDelegate> delegate;
@property (nonatomic, assign) PickerModer pcikerModer;
@property (nonatomic, strong) NSMutableArray *albums;
@property (nonatomic, strong) UITableView *tableView;
- (void)loadingAlbumInfos;
@end
@protocol ZAlbumsViewControllerDelegate <NSObject>
- (void)ZAlbumsViewController:(ZAlbumsViewController*)zalbumsVC didSelect:(ZAlbumInfo*)albumInfo;
@end
//
// ZAlbumsViewController.m
// zPic
//
// Created by zykhbl on 2017/7/22.
// Copyright © 2017年 zykhbl. All rights reserved.
//
#import "ZAlbumsViewController.h"
#import "ZAlbumTableViewCell.h"
#import "SDWebImageDecoder.h"
@implementation ZAlbumsViewController
@synthesize delegate;
@synthesize pcikerModer;
@synthesize albums;
@synthesize tableView;
- (void)requestLastImage:(PHAsset*)asset forAlbumInfo:(ZAlbumInfo*)albumInfo {
__weak typeof(self) weak_self = self;
dispatch_async(dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
[UIImage requestThumbnailsImage:asset deliveryMode:PHImageRequestOptionsDeliveryModeOpportunistic resultHandler:^(UIImage *_Nullable result, NSDictionary *_Nullable info) {
albumInfo.albumImg = [UIImage decodedOriginImage:result];
if (weak_self.tableView != nil) {
dispatch_async(dispatch_get_main_queue(), ^ {
[weak_self.tableView reloadData];
});
}
}];
});
}
- (void)foreachAlbums:(PHFetchResult<PHAssetCollection*>*)albumResult {
for (NSUInteger i = 0; i < albumResult.count; i++) {
PHAssetCollection *assetCollection = [albumResult objectAtIndex:i];
if (assetCollection.assetCollectionSubtype != PHAssetCollectionSubtypeSmartAlbumAllHidden) {
PHFetchResult<PHAsset*> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
if (assets.count > 0) {
NSUInteger photoCount = 0;
NSUInteger videoCount = 0;
ZAlbumInfo *albumInfo = nil;
for (NSInteger i = assets.count - 1; i >= 0; i--) {
PHAsset *asset = [assets objectAtIndex:i];
if (asset.mediaType == PHAssetMediaTypeImage) {
photoCount++;
if (albumInfo == nil) {
albumInfo = [[ZAlbumInfo alloc] init];
[self requestLastImage:asset forAlbumInfo:albumInfo];
}
} else if (self.pcikerModer == PickerModerOfVideo && asset.mediaType == PHAssetMediaTypeVideo) {
videoCount++;
if (albumInfo == nil) {
albumInfo = [[ZAlbumInfo alloc] init];
[self requestLastImage:asset forAlbumInfo:albumInfo];
}
}
}
if (albumInfo != nil) {
albumInfo.assetCollection = assetCollection;
albumInfo.assets = assets;
albumInfo.photoCount = photoCount;
albumInfo.videoCount = videoCount;
[self.albums addObject:albumInfo];
}
}
}
}
}
- (id)init {
self = [super init];
if (self) {
self.albums = [[NSMutableArray alloc] initWithCapacity:20];
}
return self;
}
- (void)loadingAlbumInfos {
__weak typeof(self) weak_self = self;
dispatch_async(dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
PHFetchResult<PHAssetCollection*> *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAny options:nil];
[weak_self foreachAlbums:smartAlbums];
PHFetchResult<PHAssetCollection*> *albumResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil];
[weak_self foreachAlbums:albumResult];
[weak_self.albums sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
ZAlbumInfo *albumInfo1 = (ZAlbumInfo*)obj1;
ZAlbumInfo *albumInfo2 = (ZAlbumInfo*)obj2;
if (albumInfo1.photoCount + albumInfo1.videoCount < albumInfo2.photoCount + albumInfo2.videoCount) {
return YES;
}
return NO;
}];
});
}
- (void)viewDidLoad {
[super viewDidLoad];
if (self.tableView == nil) {
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.backgroundColor= ViewBackgroupColor;
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.view addSubview:self.tableView];
}
}
//=============UITableViewDataSource=============
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
return self.albums.count;
}
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *ZAlbumTableViewCellIdentifier = @"ZAlbumTableViewCell";
ZAlbumTableViewCell *cell = (ZAlbumTableViewCell*)[self.tableView dequeueReusableCellWithIdentifier:ZAlbumTableViewCellIdentifier];
if (cell == nil) {
cell = [[ZAlbumTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ZAlbumTableViewCellIdentifier];
CGRect rect = self.view.bounds;
rect.size.height = 70.0;
cell.frame = rect;
[cell setup];
}
ZAlbumInfo *albumInfo = [self.albums objectAtIndex:indexPath.row];
cell.imgView.image = albumInfo.albumImg;
cell.nameLabel.text = albumInfo.assetCollection.localizedTitle;
if (albumInfo.photoCount > 0 && albumInfo.videoCount > 0) {
cell.countLabel.text = [NSString stringWithFormat:@"照片:%d 视频:%d", (int)albumInfo.photoCount, (int)albumInfo.videoCount];
} else if (albumInfo.photoCount > 0) {
cell.countLabel.text = [NSString stringWithFormat:@"照片:%d", (int)albumInfo.photoCount];
} else if (albumInfo.videoCount > 0) {
cell.countLabel.text = [NSString stringWithFormat:@"视频:%d", (int)albumInfo.videoCount];
} else {
cell.countLabel.text = @"";
}
return cell;
}