| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- //
- // MenuView.m
- // UIKit
- //
- // Created by kennethmiao on 2018/9/18.
- // Copyright © 2018 Tencent. All rights reserved.
- //
- #import "TUIMediaView.h"
- #import <TIMCommon/TIMDefine.h>
- #import <TIMCommon/TUIMessageCell.h>
- #import <TUICore/TUIDarkModel.h>
- #import <TUICore/TUIGlobalization.h>
- #import "TUIChatConversationModel.h"
- #import "TUIImageCollectionCell.h"
- #import "TUIMessageMediaDataProvider.h"
- #import "TUIVideoCollectionCell.h"
- #define ANIMATION_TIME 0.2
- @interface TUIMediaView () <UICollectionViewDelegate,
- UICollectionViewDataSource,
- UICollectionViewDelegateFlowLayout,
- UIScrollViewDelegate,
- TUIMediaCollectionCellDelegate>
- @property(strong, nonatomic) TUIMessageMediaDataProvider *dataProvider;
- @property(strong, nonatomic) UICollectionView *menuCollectionView;
- @property(strong, nonatomic) UIImage *saveBackgroundImage;
- @property(strong, nonatomic) UIImage *saveShadowImage;
- @property(strong, nonatomic) UIImageView *imageView;
- @property(strong, nonatomic) UIImage *thumbImage;
- @property(strong, nonatomic) UIView *coverView;
- @property(strong, nonatomic) UIView *mediaView;
- @property(assign, nonatomic) CGRect thumbFrame;
- @property(assign, nonatomic) NSIndexPath *currentVisibleIndexPath;
- @end
- @implementation TUIMediaView {
- V2TIMMessage *_curMessage;
- }
- - (instancetype)init {
- self = [super init];
- if (self) {
- _currentVisibleIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
- }
- return self;
- }
- - (void)setupViews {
- self.backgroundColor = [UIColor clearColor];
- self.coverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, Screen_Width * 3, Screen_Height * 3)];
- self.coverView.backgroundColor = [UIColor blackColor];
- [self addSubview:self.coverView];
- self.mediaView = [[UIView alloc] initWithFrame:self.thumbFrame];
- self.mediaView.backgroundColor = [UIColor clearColor];
- [self addSubview:self.mediaView];
- TUICollectionRTLFitFlowLayout *menuFlowLayout = [[TUICollectionRTLFitFlowLayout alloc] init];
- menuFlowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
- menuFlowLayout.minimumLineSpacing = 0;
- menuFlowLayout.minimumInteritemSpacing = 0;
- menuFlowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
- self.menuCollectionView = [[UICollectionView alloc] initWithFrame:self.mediaView.bounds collectionViewLayout:menuFlowLayout];
- self.menuCollectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- [self.menuCollectionView registerClass:[TUIImageCollectionCell class] forCellWithReuseIdentifier:TImageMessageCell_ReuseId];
- [self.menuCollectionView registerClass:[TUIVideoCollectionCell class] forCellWithReuseIdentifier:TVideoMessageCell_ReuseId];
- self.menuCollectionView.pagingEnabled = YES;
- self.menuCollectionView.delegate = self;
- self.menuCollectionView.dataSource = self;
- self.menuCollectionView.showsHorizontalScrollIndicator = NO;
- self.menuCollectionView.showsVerticalScrollIndicator = NO;
- self.menuCollectionView.alwaysBounceHorizontal = YES;
- self.menuCollectionView.decelerationRate = UIScrollViewDecelerationRateFast;
- self.menuCollectionView.backgroundColor = [UIColor clearColor];
- self.menuCollectionView.hidden = YES;
- [self.mediaView addSubview:self.menuCollectionView];
- self.imageView = [[UIImageView alloc] initWithFrame:self.mediaView.bounds];
- self.imageView.layer.cornerRadius = 5.0;
- [self.imageView.layer setMasksToBounds:YES];
- self.imageView.contentMode = UIViewContentModeScaleAspectFit;
- self.imageView.backgroundColor = [UIColor clearColor];
- self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- self.imageView.image = self.thumbImage;
- [self.mediaView addSubview:self.imageView];
- [UIView animateWithDuration:ANIMATION_TIME
- animations:^{
- self.mediaView.frame = self.bounds;
- }];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(ANIMATION_TIME * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [self.imageView removeFromSuperview];
- self.menuCollectionView.hidden = NO;
- });
- [[NSNotificationCenter defaultCenter] postNotificationName:kEnableAllRotationOrientationNotification object:nil];
- [self setupRotaionNotifications];
- }
- - (void)setupRotaionNotifications {
- if (@available(iOS 16.0, *)) {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(onDeviceOrientationChange:)
- name:TUIMessageMediaViewDeviceOrientationChangeNotification
- object:nil];
- } else {
- [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(onDeviceOrientationChange:)
- name:UIDeviceOrientationDidChangeNotification
- object:nil];
- }
- }
- - (void)setThumb:(UIImageView *)thumb frame:(CGRect)frame {
- self.thumbImage = thumb.image;
- self.thumbFrame = frame;
- [self setupViews];
- }
- - (void)setCurMessage:(V2TIMMessage *)curMessage {
- _curMessage = curMessage;
- TUIChatConversationModel *model = [[TUIChatConversationModel alloc] init];
- model.userID = _curMessage.userID;
- model.groupID = _curMessage.groupID;
- self.dataProvider = [[TUIMessageMediaDataProvider alloc] initWithConversationModel:model];
- [self.dataProvider loadMediaWithMessage:_curMessage];
- @weakify(self);
- [RACObserve(self.dataProvider, medias) subscribeNext:^(NSArray *x) {
- @strongify(self);
- [self.menuCollectionView reloadData];
- for (int i = 0; i < self.dataProvider.medias.count; i++) {
- TUIMessageCellData *data = self.dataProvider.medias[i];
- if ([data.innerMessage.msgID isEqualToString:self->_curMessage.msgID]) {
- self.currentVisibleIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
- [self.menuCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]
- atScrollPosition:(UICollectionViewScrollPositionLeft)animated:NO];
- return;
- }
- }
- }];
- }
- - (void)setCurMessage:(V2TIMMessage *)curMessage allMessages:(NSArray<V2TIMMessage *> *)allMessages {
- _curMessage = curMessage;
- NSMutableArray *medias = [NSMutableArray array];
- for (V2TIMMessage *message in allMessages) {
- TUIMessageCellData *data = [TUIMessageMediaDataProvider getMediaCellData:message];
- if (data) {
- [medias addObject:data];
- }
- }
- self.dataProvider = [[TUIMessageMediaDataProvider alloc] initWithConversationModel:nil];
- self.dataProvider.medias = medias;
- [self.menuCollectionView reloadData];
- for (int i = 0; i < self.dataProvider.medias.count; i++) {
- TUIMessageCellData *data = self.dataProvider.medias[i];
- if ([data.innerMessage.msgID isEqualToString:_curMessage.msgID]) {
- [self.menuCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]
- atScrollPosition:(UICollectionViewScrollPositionLeft)animated:NO];
- return;
- }
- }
- }
- - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
- return self.dataProvider.medias.count;
- }
- - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
- TUIMessageCellData *data = self.dataProvider.medias[indexPath.row];
- TUIMediaCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:data.reuseId forIndexPath:indexPath];
- if (cell) {
- cell.delegate = self;
- [cell fillWithData:data];
- if ([cell isKindOfClass:[TUIVideoCollectionCell class]]) {
- TUIVideoCollectionCell *videoCell = (TUIVideoCollectionCell *)cell;
- [videoCell reloadAllView];
- }
- else if ([cell isKindOfClass:[TUIImageCollectionCell class]]) {
- TUIImageCollectionCell *imageCell = (TUIImageCollectionCell *)cell;
- [imageCell reloadAllView];
- }
- else {
- //empty
- }
- }
- return cell;
- }
- - (CGSize)collectionView:(UICollectionView *)collectionView
- layout:(UICollectionViewLayout *)collectionViewLayout
- sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
- return collectionView.frame.size;
- }
- - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
- [super traitCollectionDidChange:previousTraitCollection];
- [self.menuCollectionView.collectionViewLayout invalidateLayout];
- }
- - (CGPoint)collectionView:(UICollectionView *)collectionView targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset {
- UICollectionViewLayoutAttributes *attrs = [collectionView layoutAttributesForItemAtIndexPath:self.currentVisibleIndexPath];
- CGPoint newOriginForOldIndex = attrs.frame.origin;
- return newOriginForOldIndex.x == 0 ? proposedContentOffset : newOriginForOldIndex;
- }
- #pragma mark TUIMediaCollectionCellDelegate
- - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
- CGPoint center = CGPointMake(scrollView.contentOffset.x + (scrollView.frame.size.width / 2), scrollView.frame.size.height / 2);
- NSIndexPath *ip = [self.menuCollectionView indexPathForItemAtPoint:center];
- if (ip) {
- self.currentVisibleIndexPath = ip;
- }
- NSArray *indexPaths = [self.menuCollectionView indexPathsForVisibleItems];
- NSIndexPath *indexPath = indexPaths.firstObject;
- TUIMessageCellData *data = self.dataProvider.medias[indexPath.row];
- _curMessage = data.innerMessage;
- if (indexPath.row <= self.dataProvider.pageCount / 2) {
- [self.dataProvider loadOlderMedia];
- }
- if (indexPath.row >= self.dataProvider.medias.count - self.dataProvider.pageCount / 2) {
- [self.dataProvider loadNewerMedia];
- }
- }
- - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
- NSArray *indexPaths = [self.menuCollectionView indexPathsForVisibleItems];
- NSIndexPath *indexPath = indexPaths.firstObject;
- UICollectionViewCell *cell = [self.menuCollectionView cellForItemAtIndexPath:indexPath];
- if ([cell isKindOfClass:[TUIVideoCollectionCell class]]) {
- TUIVideoCollectionCell *videoCell = (TUIVideoCollectionCell *)cell;
- [videoCell stopVideoPlayAndSave];
- }
- }
- #pragma mark TUIMediaCollectionCellDelegate
- - (void)onCloseMedia:(TUIMediaCollectionCell *)cell {
- if (self.onClose) {
- self.onClose();
- }
- if (self.superview) {
- [self removeFromSuperview];
- }
- [[NSNotificationCenter defaultCenter] postNotificationName:kDisableAllRotationOrientationNotification object:nil];
- }
- - (void)applyRotaionFrame {
- self.frame = CGRectMake(0, 0, Screen_Width, Screen_Height);
- self.coverView.frame = CGRectMake(0, 0, Screen_Width * 3, Screen_Height * 3);
- self.mediaView.frame = self.frame;
- self.mediaView.center = CGPointMake(self.frame.size.width / 2.0, self.frame.size.height / 2.0);
- self.menuCollectionView.frame = self.mediaView.frame;
- self.menuCollectionView.center = CGPointMake(self.frame.size.width / 2.0, self.frame.size.height / 2.0);
- [self.menuCollectionView setNeedsLayout];
- self.imageView.frame = self.mediaView.frame;
- self.imageView.center = CGPointMake(self.frame.size.width / 2.0, self.frame.size.height / 2.0);
- [self.menuCollectionView
- performBatchUpdates:^{
- }
- completion:^(BOOL finished) {
- if (finished) {
- [self.menuCollectionView scrollToItemAtIndexPath:self.currentVisibleIndexPath atScrollPosition:(UICollectionViewScrollPositionLeft)animated:NO];
- }
- }];
- return;
- }
- - (void)onDeviceOrientationChange:(NSNotification *)noti {
- [UIView performWithoutAnimation:^{
- [self applyRotaionFrame];
- }];
- }
- @end
|