Ios UIM图像之间的立方体转换
我想创建一个视图,当水平滚动时,该视图在具有立方体动画效果的Ios UIM图像之间的立方体转换,ios,swift,uiimage,Ios,Swift,Uiimage,我想创建一个视图,当水平滚动时,该视图在具有立方体动画效果的UIImage对象数组之间转换。例如: 有人能给我指出正确的方向,告诉我如何在Swift中水平滚动一组带有立方体过渡动画的UIImage对象吗?这太宽泛了,无法解释,但您可以使用此UIViewController: class CubeScrollViewController: UIViewController,UIScrollViewDelegate { var scrollView:UIScrollView? va
UIImage
对象数组之间转换。例如:
有人能给我指出正确的方向,告诉我如何在Swift中水平滚动一组带有立方体过渡动画的
UIImage
对象吗?这太宽泛了,无法解释,但您可以使用此UIViewController:
class CubeScrollViewController: UIViewController,UIScrollViewDelegate {
var scrollView:UIScrollView?
var images:[UIImage] = [UIImage]()
var imageViews:[IntegerLiteralType:UIImageView] = [IntegerLiteralType:UIImageView]()
var currentIndex = 0
var scrollOffset:CGFloat = 0.0
var previousOffset:CGFloat = 0.0
var suppressScrollEvent:Bool = false
var add = 0
override func viewDidLoad() {
super.viewDidLoad()
self.images = [UIImage(named: "image1")!,UIImage(named: "image2")!,UIImage(named:"image3")!,UIImage(named: "image4")!]
}
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
scrollView?.removeFromSuperview()
scrollView = UIScrollView(frame: self.view.frame)
scrollView?.autoresizingMask = [.FlexibleWidth,.FlexibleHeight]
scrollView?.showsHorizontalScrollIndicator = true
scrollView?.pagingEnabled = true
scrollView?.directionalLockEnabled = true;
scrollView?.autoresizesSubviews = false;
scrollView?.delegate = self
self.view.addSubview(scrollView!)
var index = 0
for image in self.images
{
let imageView = UIImageView(frame: self.view.frame)
imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true
imageView.image = image
imageView.backgroundColor = UIColor.whiteColor()
self.imageViews[index] = imageView
index += 1
}
var pages = self.images.count
if self.images.count > 1
{
pages += 2
}
self.suppressScrollEvent = true
self.scrollView?.contentSize = CGSize(width: self.view.bounds.size.width * CGFloat(pages), height: self.view.bounds.size.height)
self.suppressScrollEvent = false
self.updateContentOffset()
self.loadUnloadImageViews()
self.updateLayout()
}
func setCurrentImageIndex(currentImageIndex:IntegerLiteralType)
{
self.scrollToImageAtIndex(currentImageIndex,animated:true)
}
func scrollToImageAtIndex(index:IntegerLiteralType,animated:Bool)
{
var offset = index
if offset > self.images.count
{
offset = offset % self.images.count
}
offset = max(-1, offset)+1
scrollView?.setContentOffset(CGPoint(x: self.view.bounds.size.width * CGFloat(offset),y: 0),animated: animated)
}
func scrollForward(animated:Bool)
{
self.scrollToImageAtIndex(self.currentIndex+1, animated: animated)
}
func scrollBack(animated:Bool)
{
self.scrollToImageAtIndex(self.currentIndex-1, animated: animated)
}
func reloadData()
{
for view:UIImageView in self.imageViews.values
{
view.removeFromSuperview()
}
}
func reloadImageAtIndex(index:IntegerLiteralType,animated:Bool)
{
let image = self.images[index]
let oldImageView = self.imageViews[index]
let imageView = UIImageView(frame: self.view.frame)
imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true
imageView.image = image
imageView.backgroundColor = UIColor.whiteColor()
let transform = imageView.layer.transform
let center = imageView.center
if animated
{
let animation = CATransition()
animation.type = kCATransitionFade
self.scrollView?.layer.addAnimation(animation, forKey: nil)
}
oldImageView!.removeFromSuperview()
self.scrollView?.addSubview(imageView)
imageView.layer.transform = transform
imageView.center = center
}
func updateContentOffset()
{
var offset = self.scrollOffset
if self.images.count>1
{
offset+=1.0
while offset<1.0
{
offset+=1.0
}
while offset>=CGFloat(self.images.count+1)
{
offset-=CGFloat(self.images.count)
}
}
self.previousOffset = offset
self.suppressScrollEvent = true
self.scrollView?.contentOffset = CGPointMake(self.view.bounds.size.width*offset, 0.0)
self.suppressScrollEvent = false
}
func updateLayout()
{
for index in self.imageViews.keys
{
let imageView = self.imageViews[index]
if imageView != nil && imageView!.superview == nil
{
imageView?.layer.doubleSided = false
self.scrollView?.addSubview(imageView!)
self.add++
}
var angle = (self.scrollOffset - CGFloat(index)) * CGFloat(M_PI_2)
while angle < 0
{
angle = angle + CGFloat(M_PI * 2.0)
}
while angle > CGFloat(M_PI*2.0)
{
angle = angle - CGFloat(M_PI * 2.0)
}
var transform = CATransform3DIdentity
if angle != 0.0
{
transform.m34 = -1.0/500;
transform = CATransform3DTranslate(transform, 0.0, 0.0, -self.view.bounds.size.width / 2.0)
transform = CATransform3DRotate(transform, -angle, 0, 1, 0)
transform = CATransform3DTranslate(transform, 0, 0, self.view.bounds.size.width / 2.0)
}
imageView?.bounds = self.view.bounds
imageView?.center = CGPoint(x: self.view.bounds.size.width * 0.5 + self.scrollView!.contentOffset.x, y: self.view.bounds.size.height * 0.5);
imageView?.layer.transform = transform
}
}
func loadUnloadImageViews()
{
var visibleIndices = [IntegerLiteralType]()
visibleIndices.append(self.currentIndex)
visibleIndices.append(self.currentIndex + 1)
if self.currentIndex > 0
{
visibleIndices.append(self.currentIndex - 1)
}
else
{
visibleIndices.append(-1)
}
for index in 0...self.images.count
{
if !visibleIndices.contains(index)
{
let imageView = self.imageViews[index]
imageView?.removeFromSuperview()
self.imageViews.removeValueForKey(index)
}
}
for index in visibleIndices
{
var imageView:UIImageView? = nil
if self.imageViews[index] != nil
{
imageView = self.imageViews[index]!
}
if imageView == nil && self.images.count > 0
{
let newIndex = (index + self.images.count) % self.images.count
let imageView = UIImageView(frame: self.view.frame)
imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true
imageView.backgroundColor = UIColor.whiteColor()
imageView.image = self.images[newIndex]
self.imageViews[index] = imageView
}
}
}
func scrollViewDidScroll(scrollView: UIScrollView) {
if !self.suppressScrollEvent
{
let offset:CGFloat = scrollView.contentOffset.x / self.view.bounds.size.width
self.scrollOffset += (offset - self.previousOffset)
while self.scrollOffset < 0.0
{
self.scrollOffset += CGFloat(self.images.count)
}
while self.scrollOffset >= CGFloat(self.images.count)
{
self.scrollOffset -= CGFloat(self.images.count)
}
self.previousOffset = offset
if offset - floor(offset) == 0.0
{
self.scrollOffset = round(self.scrollOffset)
}
self.currentIndex = max(0, min(self.images.count - 1, IntegerLiteralType(round(self.scrollOffset))))
self.updateContentOffset()
self.loadUnloadImageViews()
self.updateLayout()
}
}
func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {
let nearestIntegralOffset = round(self.scrollOffset)
if abs(self.scrollOffset - nearestIntegralOffset) > 0.0
{
self.scrollToImageAtIndex(self.currentIndex, animated: true)
}
}
}
class CubeScrollViewController:UIViewController、UIScrollViewDelegate{
var scrollView:UIScrollView?
变量图像:[UIImage]=[UIImage]()
var imageViews:[IntegerLiteralType:UIImageView]=[IntegerLiteralType:UIImageView]()
var currentIndex=0
变量scrollOffset:CGFloat=0.0
var previousOffset:CGFloat=0.0
var suppressScrollEvent:Bool=false
var add=0
重写func viewDidLoad(){
super.viewDidLoad()
self.images=[UIImage(名为:“image1”)!、UIImage(名为:“image2”)、UIImage(名为:“image3”)、UIImage(名为:“image4”)!]
}
重写func viewdilayoutsubviews()
{
super.viewDidLayoutSubviews()
scrollView?.removeFromSuperview()
scrollView=UIScrollView(框架:self.view.frame)
scrollView?.autoresizingMask=[.FlexibleWidth、.FlexibleHeight]
scrollView?.showsHorizontalScrollIndicator=true
scrollView?.PaginEnabled=true
scrollView?.directionalLockEnabled=true;
scrollView?.AutoResizesSubView=false;
scrollView?.delegate=self
self.view.addSubview(scrollView!)
var指数=0
自我形象中的形象
{
让imageView=UIImageView(框架:self.view.frame)
imageView.contentMode=.ScaleSpectFill
imageView.clipsToBounds=true
imageView.image=image
imageView.backgroundColor=UIColor.whiteColor()
self.imageView[index]=imageView
指数+=1
}
var pages=self.images.count
如果self.images.count>1
{
页数+=2
}
self.suppressScrollEvent=true
self.scrollView?.contentSize=CGSize(宽度:self.view.bounds.size.width*CGFloat(页面),高度:self.view.bounds.size.height)
self.suppressScrollEvent=false
self.updateContentOffset()
self.loadUnloadImageViews()
self.updateLayout()
}
func setCurrentImageIndex(currentImageIndex:IntegerLiteralType)
{
self.ScrollToImageIndex(currentImageIndex,动画:true)
}
func ScrollToImageIndex(索引:IntegerLiteralType,动画:Bool)
{
var偏移=指数
如果偏移>self.images.count
{
偏移量=偏移量%self.images.count
}
偏移量=最大值(-1,偏移量)+1
scrollView?.setContentOffset(CGPoint(x:self.view.bounds.size.width*CGFloat(offset),y:0),动画:动画)
}
func向前滚动(动画:Bool)
{
self.ScrollToImageIndex(self.currentIndex+1,动画:动画)
}
func回滚(动画:Bool)
{
self.scrollToImageIndex(self.currentIndex-1,动画:动画)
}
func重载数据()
{
对于视图:self.imageview.values中的UIImageView
{
view.removeFromSuperview()视图
}
}
func重新加载ImageAtIndex(索引:IntegerLiteralType,动画:Bool)
{
让image=self.images[index]
让oldImageView=self.imageViews[index]
让imageView=UIImageView(框架:self.view.frame)
imageView.contentMode=.ScaleSpectFill
imageView.clipsToBounds=true
imageView.image=image
imageView.backgroundColor=UIColor.whiteColor()
让transform=imageView.layer.transform
让中心=imageView.center
如果动画
{
让动画=CATTransition()
animation.type=kCATransitionFade
self.scrollView?.layer.addAnimation(动画,forKey:nil)
}
oldImageView!.removeFromSuperview()
self.scrollView?.addSubview(图像视图)
imageView.layer.transform=转换
imageView.center=center
}
func updateContentOffset()
{
var offset=self.scrollOffset
如果self.images.count>1
{
偏移量+=1.0
而offset=CGFloat(self.images.count+1)
{
偏移量-=CGFloat(self.images.count)
}
}
self.previousOffset=偏移量
self.suppressScrollEvent=true
self.scrollView?.contentOffset=CGPointMake(self.view.bounds.size.width*offset,0.0)
self.suppressScrollEvent=false
}
func updateLayout()
{
对于self.imageview.keys中的索引
{
让imageView=self.imageViews[索引]
如果imageView!=nil&&imageView!.superview==nil
{
imageView?.layer.doubleside=false
self.scrollView?.addSubview(imageView!)
自我添加++
}
变量角度=(self.scrollOffset-CGFloat(索引))*CGFloat(M_PI_2)
当角度<0时
{
角度=角度+CGFloat(M_PI*2.0)
}
当角度>CGFloat时(M_PI*2.0)
{
角度=角度-CGFloat(M_PI*2.0)
}
var transform=CATTransferM3DidEntity
如果角度!=0.0
{
transform.m34=-1.0/500;
transform=CATTransformerM3DTTranslate(transform,0.0,0.0,-self.view.bounds.size.width/2.0)
变换=CATTransferM3dRotate(变换,-角度,0,1,0)
transform=CATTransformerM3DTTranslate(transform,0,0,self.view.bounds.size.width/2.0)
}
imageView?.bounds=self.view.bounds
imageView?.center=CGPoint(x:self.view.bounds.size.width*0.5+self.scrollView!.contentOffset.x,y:self.view)。
import UIKit
public class CubeScrollViewController: UIViewController
{
//MARK: - Properties
private lazy var scrollView: UIScrollView =
{
let scrollView = UIScrollView()
scrollView.autoresizingMask = [.flexibleWidth,.flexibleHeight]
scrollView.showsHorizontalScrollIndicator = true
scrollView.isPagingEnabled = true
scrollView.isDirectionalLockEnabled = true;
scrollView.autoresizesSubviews = false;
scrollView.delegate = self
return scrollView
}()
var images = [UIImage]()
fileprivate var imageViews = [Int: UIImageView]()
fileprivate var currentIndex = 0
fileprivate var scrollOffset: CGFloat = 0.0
fileprivate var previousOffset: CGFloat = 0.0
fileprivate var suppressScrollEvent = false
//MARK: - Lifecycle
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addSubview(self.scrollView)
for (index, image) in self.images.enumerated()
{
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.backgroundColor = UIColor.white
self.imageViews[index] = imageView
}
}
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
self.scrollView.frame = self.view.bounds
self.imageViews.values.forEach { $0.frame = self.view.bounds }
var pages = CGFloat(self.images.count)
pages = self.images.count > 1 ? pages + 2 : pages
self.suppressScrollEvent = true
self.scrollView.contentSize = CGSize(width: self.view.bounds.width * pages, height: self.view.bounds.height)
self.suppressScrollEvent = false
self.updateContentOffset()
self.loadUnloadViews()
self.updateLayout()
}
//MARK: - Exposed Functions
func set(_ currentImageIndex: Int)
{
self.scrollToImage(at: currentIndex)
}
func scrollToImage(at index: Int, animated: Bool = true)
{
var offset = index > self.images.count ? index % self.images.count : index
offset = max(-1, offset) + 1
self.scrollView.setContentOffset(CGPoint(x: self.view.bounds.width * CGFloat(offset), y: 0.0), animated: animated)
}
func scrollForward(animated: Bool = true)
{
self.scrollToImage(at: self.currentIndex + 1, animated: animated)
}
func scrollBack(animated: Bool = true)
{
self.scrollToImage(at: self.currentIndex - 1, animated: animated)
}
func reloadData()
{
self.imageViews.values.forEach { $0.removeFromSuperview() }
}
func reloadImage(at index: Int, animated: Bool = true)
{
guard 0 ..< self.images.count ~= index else { return }
let image = self.images[index]
let oldImageView = self.imageViews[index]
let imageView = UIImageView(frame: self.view.bounds)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.image = image
imageView.backgroundColor = .white
let transform = imageView.layer.transform
let center = imageView.center
if animated
{
let animation = CATransition()
animation.type = kCATransitionFade
self.scrollView.layer.add(animation, forKey: nil)
}
oldImageView?.removeFromSuperview()
self.scrollView.addSubview(imageView)
imageView.layer.transform = transform
imageView.center = center
}
//MARK: - Layout
fileprivate func updateContentOffset()
{
guard self.images.count > 1 else { return }
var offset = self.scrollOffset
offset += 1.0
while offset < 1.0
{
offset += 1.0
}
while offset >= CGFloat(self.images.count + 1)
{
offset -= CGFloat(self.images.count)
}
self.previousOffset = offset
self.suppressScrollEvent = true
self.scrollView.contentOffset = CGPoint(x: self.view.bounds.width * offset, y: 0.0)
self.suppressScrollEvent = false
}
fileprivate func updateLayout()
{
for index in self.imageViews.keys
{
guard let imageView = self.imageViews[index] else { continue }
if imageView.superview == nil
{
imageView.layer.isDoubleSided = false
self.scrollView.addSubview(imageView)
}
var angle = (self.scrollOffset - CGFloat(index)) * CGFloat.pi * 0.5
while angle < 0
{
angle += CGFloat.pi * 2.0
}
while angle > CGFloat.pi * 2.0
{
angle -= CGFloat.pi * 2.0
}
var transform = CATransform3DIdentity
if angle != 0.0
{
transform.m34 = -1.0 / 500.0
transform = CATransform3DTranslate(transform, 0.0, 0.0, -self.view.bounds.width * 0.5)
transform = CATransform3DRotate(transform, -angle, 0, 1, 0)
transform = CATransform3DTranslate(transform, 0, 0, self.view.bounds.width * 0.5)
}
imageView.bounds = self.view.bounds
imageView.center = CGPoint(x: self.view.bounds.midX + self.scrollView.contentOffset.x, y: self.view.bounds.midY)
imageView.layer.transform = transform
}
}
fileprivate func loadUnloadViews()
{
var visibleIndices = [Int]()
visibleIndices.append(self.currentIndex)
visibleIndices.append(self.currentIndex + 1)
if self.currentIndex > 0
{
visibleIndices.append(self.currentIndex - 1)
}
else
{
visibleIndices.append(-1)
}
for index in 0 ..< self.images.count
{
guard !visibleIndices.contains(index) else { continue }
let imageView = self.imageViews[index]
imageView?.removeFromSuperview()
self.imageViews.removeValue(forKey: index)
}
for index in visibleIndices
{
if let _ = self.imageViews[index]
{
}
else if self.images.count > 0
{
let newIndex = (index + self.images.count) % self.images.count
let imageView = UIImageView(frame: self.view.bounds)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.backgroundColor = .white
imageView.image = self.images[newIndex]
self.imageViews[index] = imageView
}
}
}
}
// MARK: - UIScrollViewDelegate
extension CubeScrollViewController: UIScrollViewDelegate
{
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
guard !self.suppressScrollEvent else { return }
let offset: CGFloat = scrollView.contentOffset.x / self.view.bounds.width
self.scrollOffset += (offset - self.previousOffset)
while self.scrollOffset < 0.0
{
self.scrollOffset += CGFloat(self.images.count)
}
while self.scrollOffset >= CGFloat(self.images.count)
{
self.scrollOffset -= CGFloat(self.images.count)
}
self.previousOffset = offset
if offset - floor(offset) == 0.0
{
self.scrollOffset = round(self.scrollOffset)
}
self.currentIndex = max(0, min(self.images.count - 1, Int(round(self.scrollOffset))))
self.updateContentOffset()
self.loadUnloadViews()
self.updateLayout()
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView)
{
let nearestIntegralOffset = round(self.scrollOffset)
guard abs(self.scrollOffset - nearestIntegralOffset) > 0.0 else { return }
self.scrollToImage(at: self.currentIndex)
}
}
import UIKit
class ViewController: UIViewController
{
//MARK: - Properties
private lazy var scrollView: UIScrollView =
{
let scrollView = UIScrollView()
scrollView.autoresizingMask = [.flexibleWidth,.flexibleHeight]
scrollView.showsHorizontalScrollIndicator = true
scrollView.isPagingEnabled = true
scrollView.isDirectionalLockEnabled = true;
scrollView.autoresizesSubviews = false;
scrollView.delegate = self
return scrollView
}()
var images = [UIImage]()
fileprivate var imageViews = [Int: UIImageView]()
fileprivate var currentIndex = 0
fileprivate var scrollOffset: CGFloat = 0.0
fileprivate var previousOffset: CGFloat = 0.0
fileprivate var suppressScrollEvent = false
//MARK: - Lifecycle
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addSubview(self.scrollView)
for (index, image) in self.images.enumerated()
{
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.backgroundColor = UIColor.white
self.imageViews[index] = imageView
}
}
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
self.scrollView.frame = self.view.bounds
let width = UIScreen.main.bounds.size.width - 80
let yPos = (UIScreen.main.bounds.size.height / 2) - (width / 2)
let iFrame = CGRect(x: 40, y: yPos, width: width, height: width)
self.imageViews.values.forEach { $0.frame = iFrame }
var pages = CGFloat(self.images.count)
pages = self.images.count > 1 ? pages + 2 : pages
self.suppressScrollEvent = true
self.scrollView.contentSize = CGSize(width: self.view.bounds.width * pages, height: self.view.bounds.height)
self.suppressScrollEvent = false
self.updateContentOffset()
self.loadUnloadViews()
self.updateLayout()
}
//MARK: - Exposed Functions
func set(_ currentImageIndex: Int)
{
self.scrollToImage(at: currentIndex)
}
func scrollToImage(at index: Int, animated: Bool = true)
{
var offset = index > self.images.count ? index % self.images.count : index
offset = max(-1, offset) + 1
self.scrollView.setContentOffset(CGPoint(x: self.view.bounds.width * CGFloat(offset), y: 0.0), animated: animated)
}
func scrollForward(animated: Bool = true)
{
self.scrollToImage(at: self.currentIndex + 1, animated: animated)
}
func scrollBack(animated: Bool = true)
{
self.scrollToImage(at: self.currentIndex - 1, animated: animated)
}
func reloadData()
{
self.imageViews.values.forEach { $0.removeFromSuperview() }
}
func reloadImage(at index: Int, animated: Bool = true)
{
let width = UIScreen.main.bounds.size.width - 80
let yPos = (UIScreen.main.bounds.size.height / 2) - (width / 2)
let iFrame = CGRect(x: 40, y: yPos, width: width, height: width)
guard 0 ..< self.images.count ~= index else { return }
let image = self.images[index]
let oldImageView = self.imageViews[index]
let imageView = UIImageView(frame: iFrame)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.image = image
imageView.backgroundColor = .white
let transform = imageView.layer.transform
let center = imageView.center
if animated
{
let animation = CATransition()
animation.type = CATransitionType.fade
self.scrollView.layer.add(animation, forKey: nil)
}
oldImageView?.removeFromSuperview()
self.scrollView.addSubview(imageView)
imageView.layer.transform = transform
imageView.center = center
}
//MARK: - Layout
fileprivate func updateContentOffset()
{
guard self.images.count > 1 else { return }
var offset = self.scrollOffset
offset += 1.0
while offset < 1.0
{
offset += 1.0
}
while offset >= CGFloat(self.images.count + 1)
{
offset -= CGFloat(self.images.count)
}
self.previousOffset = offset
self.suppressScrollEvent = true
self.scrollView.contentOffset = CGPoint(x: self.view.bounds.width * offset, y: 0.0)
self.suppressScrollEvent = false
}
fileprivate func updateLayout()
{
let width = UIScreen.main.bounds.size.width - 80
let yPos = (UIScreen.main.bounds.size.height / 2) - (width / 2)
let iFrame = CGRect(x: 40, y: yPos, width: width, height: width)
for index in self.imageViews.keys
{
guard let imageView = self.imageViews[index] else { continue }
if imageView.superview == nil
{
imageView.layer.isDoubleSided = false
self.scrollView.addSubview(imageView)
}
var angle = (self.scrollOffset - CGFloat(index)) * CGFloat.pi * 0.5
while angle < 0
{
angle += CGFloat.pi * 2.0
}
while angle > CGFloat.pi * 2.0
{
angle -= CGFloat.pi * 2.0
}
var transform = CATransform3DIdentity
if angle != 0.0
{
transform.m34 = -1.0 / 500.0
transform = CATransform3DTranslate(transform, 0.0, 0.0, -iFrame.width * 0.5)
transform = CATransform3DRotate(transform, -angle, 0, 1, 0)
transform = CATransform3DTranslate(transform, 0, 0, iFrame.width * 0.5)
}
imageView.bounds = iFrame
imageView.center = CGPoint(x: iFrame.midX + self.scrollView.contentOffset.x, y: iFrame.midY)
imageView.layer.transform = transform
}
}
fileprivate func loadUnloadViews()
{
var visibleIndices = [Int]()
visibleIndices.append(self.currentIndex)
visibleIndices.append(self.currentIndex + 1)
if self.currentIndex > 0
{
visibleIndices.append(self.currentIndex - 1)
}
else
{
visibleIndices.append(-1)
}
for index in 0 ..< self.images.count
{
guard !visibleIndices.contains(index) else { continue }
let imageView = self.imageViews[index]
imageView?.removeFromSuperview()
self.imageViews.removeValue(forKey: index)
}
for index in visibleIndices
{
if let _ = self.imageViews[index]
{
}
else if self.images.count > 0
{
let width = UIScreen.main.bounds.size.width - 80
let yPos = (UIScreen.main.bounds.size.height / 2) - (width / 2)
let iFrame = CGRect(x: 40, y: yPos, width: width, height: width)
let newIndex = (index + self.images.count) % self.images.count
let imageView = UIImageView(frame: iFrame)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.backgroundColor = .white
imageView.image = self.images[newIndex]
self.imageViews[index] = imageView
}
}
}
}
// MARK: - UIScrollViewDelegate
extension ViewController: UIScrollViewDelegate
{
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
guard !self.suppressScrollEvent else { return }
let offset: CGFloat = scrollView.contentOffset.x / self.view.bounds.width
self.scrollOffset += (offset - self.previousOffset)
while self.scrollOffset < 0.0
{
self.scrollOffset += CGFloat(self.images.count)
}
while self.scrollOffset >= CGFloat(self.images.count)
{
self.scrollOffset -= CGFloat(self.images.count)
}
self.previousOffset = offset
if offset - floor(offset) == 0.0
{
self.scrollOffset = round(self.scrollOffset)
}
self.currentIndex = max(0, min(self.images.count - 1, Int(round(self.scrollOffset))))
self.updateContentOffset()
self.loadUnloadViews()
self.updateLayout()
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView)
{
let nearestIntegralOffset = round(self.scrollOffset)
guard abs(self.scrollOffset - nearestIntegralOffset) > 0.0 else { return }
self.scrollToImage(at: self.currentIndex)
}
}