图像幻灯片 Swift ios
Posted
技术标签:
【中文标题】图像幻灯片 Swift ios【英文标题】:Image Slideshow Swift ios 【发布时间】:2015-02-24 06:22:39 【问题描述】:我是 ios 开发新手。我正在尝试制作一个简单的全屏图像幻灯片。向左滑动时,幻灯片应显示下一张图片,向右滑动时幻灯片应显示上一张图片。
我有它的工作,但是,如果我快速连续滑动,我会得到一个空白屏幕,几乎就像动画没有跟上一样,然后当我等待片刻并再次滑动时,图像视图会加速进入放置并再次正常工作。知道我做错了什么吗?在使用动态数量的图像(这里它们是硬编码的)实现这样的图像轮播时,最佳实践是什么?
import UIKit
var imageArr = ["imageOne.jpg", "imageTwo.jpg", "imageThree.jpg", "imageFour.jpg", "imageFive.jpg"]
var imageIndex = 0;
class ViewController: UIViewController
var currImage = UIImageView()
var rightImage = UIImageView()
var leftImage = UIImageView()
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var bounds:CGRect = UIScreen.mainScreen().bounds
var width:CGFloat = bounds.size.width
var height:CGFloat = bounds.size.height
currImage.frame = CGRect(x: 0.0, y: 0.0, width: width, height: height)
currImage.image = UIImage(named: imageArr[imageIndex])
rightImage.frame = CGRect(x: width, y: 0.0, width: width, height: height)
rightImage.image = UIImage(named: imageArr[imageIndex + 1])
leftImage.frame = CGRect(x: -width, y: 0.0, width: width, height: height)
leftImage.image = UIImage(named: imageArr[imageArr.count - 1])
self.view.addSubview(currImage)
self.view.addSubview(rightImage)
self.view.addSubview(leftImage)
var swipeLeft = UISwipeGestureRecognizer(target: self, action: "handleSwipe:")
swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
self.view.addGestureRecognizer(swipeLeft)
var swipeRight = UISwipeGestureRecognizer(target: self, action: "handleSwipe:")
swipeRight.direction = UISwipeGestureRecognizerDirection.Right
self.view.addGestureRecognizer(swipeRight)
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
let transitionManager = TransitionManager()
func handleSwipe(gesture: UIGestureRecognizer)
var bounds:CGRect = UIScreen.mainScreen().bounds
var width:CGFloat = bounds.size.width
var height:CGFloat = bounds.size.height
if let swipeGesture = gesture as? UISwipeGestureRecognizer
if (swipeGesture.direction == UISwipeGestureRecognizerDirection.Left )
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.2, options: UIViewAnimationOptions.CurveEaseIn, animations:
self.currImage.frame = CGRect(x: -width, y: 0.0, width: width, height: height)
self.rightImage.frame = CGRect(x: 0.0, y:0.0, width: width, height: height)
, completion: finished in
if (!finished) return
imageIndex++
imageIndex = imageIndex <= imageArr.count-1 ? imageIndex : 0
var leftIndex = imageIndex - 1 < 0 ? imageArr.count - 1 : imageIndex - 1
self.leftImage.image = UIImage(named: imageArr[leftIndex])
self.leftImage.frame = CGRect(x: -width, y: 0.0, width: width, height: height)
var tempImg = self.currImage
self.currImage = self.rightImage
self.rightImage = tempImg
self.rightImage.frame = CGRect(x: width, y: 0.0, width: width, height: height)
var rightIndex = imageIndex + 1 > imageArr.count - 1 ? 0 : imageIndex + 1
self.rightImage.image = UIImage(named: imageArr[rightIndex])
)
if (swipeGesture.direction == UISwipeGestureRecognizerDirection.Right)
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.2, options: UIViewAnimationOptions.CurveEaseIn, animations:
self.currImage.frame = CGRect(x: width, y: 0.0, width: width, height: height)
self.leftImage.frame = CGRect(x: 0.0, y: 0.0, width: width, height: height)
, completion: finished in
imageIndex--
imageIndex = imageIndex < 0 ? imageArr.count - 1 : imageIndex
var rightIndex = imageIndex + 1 > imageArr.count - 1 ? 0 : imageIndex + 1
self.rightImage.image = UIImage(named: imageArr[rightIndex])
self.rightImage.frame = CGRect(x: width, y: 0.0, width: width, height: height)
var tempImg = self.currImage
self.currImage = self.tempImg
self.leftImage = tempCurr
self.leftImage.frame = CGRect(x: -width, y: 0.0, width: width, height: height)
var leftIndex = imageIndex - 1 < 0 ? imageArr.count - 1 : imageIndex - 1
self.leftImage.image = UIImage(named: imageArr[leftIndex])
)
非常感谢任何帮助!
【问题讨论】:
在这一行:self.leftImage = tempCurr tempCurr 是什么?出现编译错误。 我想通了:var tempImg = self.currImage self.currImage = self.leftImage self.leftImage = tempImg
【参考方案1】:
@IBOutlet weak var imageView:UIImageView!
var i=Int()
override func viewDidLoad()
super.viewDidLoad()
Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(imageChange), userInfo: nil, repeats: true)
// Do any additional setup after loading the view.
@objc func imageChange()
self.imageView.image=images[i]
if i<images.count-1
i+=1
else
i=0
【讨论】:
【参考方案2】:我已尝试将 CollectionView 用于轮播幻灯片,但对我来说并不奏效。我不喜欢为了让它在一行中显示图像而不得不采取的骇人听闻的方式,我也不喜欢它无法返回活动图像的事实(这里也有一些解决方法,但他们不看起来可靠)。因此,很自然地,我最终为我的目的构建了一个自定义幻灯片轮播。我将在这里分享代码,希望它可以帮助(或至少指导某人)遇到类似问题。
注意:我的轮播是全宽的,singleImagePerScreen 轮播,带有滑动识别器来滑动图像,并在图像处于活动状态时触发委托功能(我用它来显示活动图像 - “1 of 5”)。
已测试:SWIFT 5、XCode 12.2、iOS 14.2
// ImageCarouselView class
import UIKit
class ImageCarouselView: UIView
private let images: [UIImage?]
private var index = 0
private let screenWidth = UIScreen.main.bounds.width
var delegate: ImageCarouselViewDelegate?
lazy var previousImageView = imageView(image: nil, contentMode: .scaleAspectFit)
lazy var currentImageView = imageView(image: nil, contentMode: .scaleAspectFit)
lazy var nextImageView = imageView(image: nil, contentMode: .scaleAspectFit)
lazy var previousImageLeadingConstraint: NSLayoutConstraint =
return previousImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: -screenWidth)
()
lazy var currentImageLeadingConstraint: NSLayoutConstraint =
return currentImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0)
()
lazy var nextImageLeadingConstraint: NSLayoutConstraint =
return nextImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: screenWidth)
()
init(_ images: [UIImage?])
self.images = images
super.init(frame: .zero)
self.translatesAutoresizingMaskIntoConstraints = false
setupLayout()
setupImages()
setupSwipeRecognizer()
required init?(coder: NSCoder)
fatalError("init(coder:) has not been implemented")
private func setupLayout()
self.subviews.forEach( $0.removeFromSuperview() )
addSubview(previousImageView)
addSubview(currentImageView)
addSubview(nextImageView)
previousImageLeadingConstraint = previousImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: -screenWidth)
currentImageLeadingConstraint = currentImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0)
nextImageLeadingConstraint = nextImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: screenWidth)
NSLayoutConstraint.activate([
previousImageLeadingConstraint,
previousImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
previousImageView.widthAnchor.constraint(equalToConstant: screenWidth),
currentImageLeadingConstraint,
currentImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
currentImageView.widthAnchor.constraint(equalToConstant: screenWidth),
nextImageLeadingConstraint,
nextImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
nextImageView.widthAnchor.constraint(equalToConstant: screenWidth),
])
private func setupImages()
currentImageView.image = images[self.index]
guard images.count > 1 else return
if (index == 0)
previousImageView.image = images[images.count - 1]
nextImageView.image = images[index + 1]
if (index == (images.count - 1))
previousImageView.image = images[index - 1]
nextImageView.image = images[0]
private func setupSwipeRecognizer()
guard images.count > 1 else return
let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes))
let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes))
leftSwipe.direction = .left
rightSwipe.direction = .right
self.addGestureRecognizer(leftSwipe)
self.addGestureRecognizer(rightSwipe)
@objc private func handleSwipes(_ sender: UISwipeGestureRecognizer)
if (sender.direction == .left)
showNextImage()
if (sender.direction == .right)
showPreviousImage()
private func showPreviousImage()
previousImageLeadingConstraint.constant = 0
currentImageLeadingConstraint.constant = screenWidth
UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations:
self.layoutIfNeeded()
, completion: _ in
self.nextImageView = self.currentImageView
self.currentImageView = self.previousImageView
self.previousImageView = self.imageView(image: nil, contentMode: .scaleAspectFit)
self.index = self.index == 0 ? self.images.count - 1 : self.index - 1
self.delegate?.imageCarouselView(self, didShowImageAt: self.index)
self.previousImageView.image = self.index == 0 ? self.images[self.images.count - 1] : self.images[self.index - 1]
self.setupLayout()
)
private func showNextImage()
nextImageLeadingConstraint.constant = 0
currentImageLeadingConstraint.constant = -screenWidth
UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations:
self.layoutIfNeeded()
, completion: _ in
self.previousImageView = self.currentImageView
self.currentImageView = self.nextImageView
self.nextImageView = self.imageView(image: nil, contentMode: .scaleAspectFit)
self.index = self.index == (self.images.count - 1) ? 0 : self.index + 1
self.delegate?.imageCarouselView(self, didShowImageAt: self.index)
self.nextImageView.image = self.index == (self.images.count - 1) ? self.images[0] : self.images[self.index + 1]
self.setupLayout()
)
func imageView(image: UIImage? = nil, contentMode: UIImageView.ContentMode) -> UIImageView
let view = UIImageView()
view.image = image
view.contentMode = contentMode
view.translatesAutoresizingMaskIntoConstraints = false
return view
// ImageCarouselViewDelegate
import UIKit
protocol ImageCarouselViewDelegate: NSObjectProtocol
func imageCarouselView(_ imageCarouselView: ImageCarouselView, didShowImageAt index: Int)
// Usage
let slideshowView = ImageCarouselView(images) // initialize
self.slideshowView.delegate = self // set delegate in viewDidLoad()
extension YourViewController: ImageCarouselViewDelegate
func imageCarouselView(_ imageCarouselView: ImageCarouselView, didShowImageAt index: Int)
// do something with index
【讨论】:
【参考方案3】:您可以添加集合视图,在自定义集合视图单元格中添加图像,然后在集合视图的道具面板上执行 选中 Paging Enabled
。使用定时器自动滑动
【讨论】:
我在这里是因为我认为这种方法可行。但在不同的屏幕尺寸下,这种方法会产生问题以上是关于图像幻灯片 Swift ios的主要内容,如果未能解决你的问题,请参考以下文章
在幻灯片 iOS APP 中从 URL Xcode 9 加载图像
在 iOS 中为视频幻灯片而不是图像使用 Open Cover Flow