
動效還是欠缺了很多,希望各位能夠指正. 個人并不是非常喜歡用框架. 所以想寫一些比較實用的功能做一個展示.
只是為了實現(xiàn)上面的功能, 所以建立了兩個collectionView,
一個用于展示圖片(所有圖片),
一個用于點擊后放大圖片并進行展示.
(并且可以實現(xiàn)左右展示,很像以前學過的水平布局展示的collectionView)
遇到的幾個問題
1.需要處理的是彈出collectionView的數(shù)據(jù)展示問題, 以及當前展示的哪張圖片問題.
2.監(jiān)測到手指點擊的cell,到底處在屏幕的哪個位置上.
3.圖片放大縮小, 會影響外邊蒙版的透明度.
額外問題, 當我彈出控制器的時候,會牽扯到將原有模型數(shù)組中的模型中的圖片取出.
1.當時我想著可以遍歷模型數(shù)組然后取出. 于是就在建立數(shù)組的時候(模型裝數(shù)組的時候), 將需要傳入的圖片一起轉換過來放入數(shù)組中 . 但是我發(fā)現(xiàn)會出現(xiàn) 加載程序變慢的情況. (廢棄掉)
2.后來我認為可以開辟一個子線程,然后用于專門加載要顯示的圖片,但到后面,如果我點擊過快的話, 很出現(xiàn)數(shù)組越界的情況(數(shù)組還沒有將數(shù)據(jù)完全加載).
3.后來我不去把加載圖片的環(huán)節(jié)放在當前控制器中處理(本來就該如此,誰的事件 就交給誰處理好了). 然后將字符串url傳入就可以了.
代碼的相關實現(xiàn)
1.對于控制器的處理,點擊Item需要將1.所有數(shù)據(jù) 2.當前點擊的indexPath傳入
modal的控制器進行接收. 展示數(shù)據(jù), 并將顯示轉到傳入的indexPath.
modal出來的控制器,展示數(shù)據(jù),并且把需要顯示indexPath轉到顯示
當點擊item的時候,可以通過設置 modal出來的控制器的數(shù)據(jù) 和展示的 indexPath來控制 modal出來的控制器的顯示
實現(xiàn)代碼
// 為了確保數(shù)據(jù)加載完全, 就在viewWillAppear中書寫跳轉
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.collectionView scrollToItemAtIndexPath:self.indexPath atScrollPosition:UICollectionViewScrollPositionRight animated:NO];
}
2.現(xiàn)在就是第二個難點的處理, 上一篇文章我們可以看出,只要給我們位置,我們可以以我們想要的數(shù)據(jù)方式進行彈出和關閉,
此時我們需要記錄的是, 點擊item的尺寸 和 點擊item的中心點的位置,這樣我們才能更精確的控制modal控制器的彈出.
在modal新的控制器的時候,我們需要做的事情有
- (void)clickShopCell:(LXLShopCell *)cell
{
// 創(chuàng)建需要modal的控制器
ModalViewController *modalVC = [[ModalViewController alloc]init];
// 設置傳入的數(shù)據(jù)
modalVC.images = self.images;
// 設置modal的控制器的代理
modalVC.delegate = self;
// 自定義轉場, 設置modal控制器的轉場代理, 利用代理去控制,轉場動畫
modalVC.transitioningDelegate = self.custom;
// 將轉場的類型改為自定義, 自己才可以進行修改
modalVC.modalPresentationStyle = UIModalPresentationCustom;
// 取得點擊cell 的frame 在控制器view上的
必須書寫 superView 否則 就會轉換不成功
#warning 必須寫superView
CGRect frame = [cell.superview convertRect:cell.frame toView:self.view];
// 獲取點擊cell的中心點 處在控制器view的什么位置上
CGPoint center = [cell.superview convertPoint:cell.center toView:self.view];
// 轉場動畫需要這兩個值的出入
self.custom.rect = frame;
self.custom.center = center;
// 后期需要. 當滑動collectionView的時候, 需要轉換成不同的中心點.
modalVC.custom = self.custom;
// 獲取點擊cell的indexPath
modalVC.indexPath = [self.collectionView indexPathForCell:cell];
[self presentViewController:modalVC animated:YES completion:^{
}];
}
轉場代理中的代碼實現(xiàn)
只進行轉場動畫的代碼說明
想法: 1.中心點的遷移
點擊中心點---->屏幕中心點
2.尺寸的變化
原cell的尺寸--->全屏幕
需要倒著思考, 本來應該是屏幕中心 ,現(xiàn)在在cell的中線點上.
本來是全屏幕, 現(xiàn)在 transform 到cell的尺寸上
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIView *presentView = [[UIView alloc]init];
// 先進行計算,需要transformScale的大小
CGFloat scaleX = self.rect.size.width / [UIScreen mainScreen].bounds.size.width;
CGFloat scaleY = self.rect.size.height / [UIScreen mainScreen].bounds.size.height;
// 對彈出控制器進行設置動畫
// 彈出前的位置,尺寸
if (self.isPop) {
presentView = [transitionContext viewForKey:UITransitionContextToViewKey];
[[transitionContext containerView] addSubview:presentView];
CGPoint point = presentView.center;
presentView.center = self.center;
presentView.transform = CGAffineTransformMakeScale(scaleX , scaleY);
// 動畫modal過程,還原尺寸和位置
[UIView animateWithDuration:1.0 animations:^{
presentView.center = point;
presentView.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
// 完成后記得關閉上下文, 否則后面的動畫將無法執(zhí)行
[transitionContext completeTransition:YES];
}];
}else
{
presentView = [transitionContext viewForKey:UITransitionContextFromViewKey];
[[transitionContext containerView] addSubview:presentView];
[UIView animateWithDuration:1.0 animations:^{
presentView.center = self.center;
presentView.transform = CGAffineTransformMakeScale(scaleX, scaleY);
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
}
3.寫到這里我想基本功能應該是可以實現(xiàn)了, 但是當我們滑動modal控制器的圖片時發(fā)現(xiàn), dismiss的時候位置不是需要回退的cell 的位置, 因為此時點擊的cell 和我需要回退的cell 已經不是一個了.
這里我們遇到了問題,那么怎么解決呢. 很簡單. 當我們滾動的時候,通知控制器,當前展示的是第幾個item, 然后他將對應cell的中心點,再傳給轉場代理就可以了
過程雖然復雜,但是也好做的
modal控制器中的代碼的實現(xiàn)
// 蘋果提供的方法, 方便我們找到離開實現(xiàn)的cell ,當時我還想找到需要的cell ,但是發(fā)現(xiàn)開始的移動根本就不可能找到. 但是此方法是針對與 拖動collectionView展示新的cell時調用, 我們確實需要
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
// 我利用 可顯示的cell 的集合, 反正我設置的頁面之內只能顯示一個. 取出顯示的cell
UICollectionViewCell *selectCell = collectionView.visibleCells.lastObject;
// 得到它的indexPath
NSIndexPath *index = [collectionView indexPathForCell:selectCell];
// 調用代理將 indexPath 傳給控制器, 那么控制器就能方便的算出中心點了
if ([self.delegate respondsToSelector:@selector(modalViewController:displayCellIndexPath:)]) {
[self.delegate modalViewController:self displayCellIndexPath:index];
}
}
控制器中的代碼
只寫了modal控制器的代理部分代碼
- (void)modalViewController:(ModalViewController *)modalVC displayCellIndexPath:(NSIndexPath *)indexPath
{
// 取出cell
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
// 算出中心點
CGPoint center = [cell.superview convertPoint:cell.center toView:self.view];
// 給轉場代理 設置 值center
self.custom.center = center;
}
現(xiàn)在圖片展示功能基本實現(xiàn)了, 下一次,我想研究研究 圖文混排的的實現(xiàn)...