Skip to content

Instantly share code, notes, and snippets.

@seka
Last active August 16, 2016 00:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seka/af8dcd27e495a0015457 to your computer and use it in GitHub Desktop.
Save seka/af8dcd27e495a0015457 to your computer and use it in GitHub Desktop.
views infinite scrolling - 擬似的な無限スクロールを実装
//
// ScrollViewController.swift
// ScrollView
//
// Created by PxP_ss on 2014/10/08.
// Copyright (c) 2014年 pxp_ss. All rights reserved.
//
import UIKit
class ScrollViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet weak var scrollView: UIScrollView!
let testImagesName = [
"test1.png"
, "test2.png"
, "test3.png"
, "test4.png"
, "test5.png"
]
// 左に移動したか右に移動したかを判別するためのステータス
enum ScrollDirection {
case kScrollDirectionLeft
case kScrollDirectionRight
}
// 画像の表示数
var maxDisplayViewNum = 0
// 画像のサイズ
let imageWidth :CGFloat = 210
let imageHeight:CGFloat = 105
// スクロール数の限界値(擬似的に無限スクロールしているように見せかけている)
let maxScrollableImages = 10000
// 画面に映る最も左端の画像のインデックス
var leftImageIndex:NSInteger = 0
// 画面外に待機している両端の画像のインデックス
var leftViewIndex :NSInteger = 0
var rightViewIndex:NSInteger = 0
var images = NSMutableArray()
/**
* viewDidLoad
* 画面が描画される際に1度だけ実行される、各種変数などの初期化処理に仕様
*/
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
for (var i = 0; i < self.testImagesName.count; i++){
var iv = UIImageView()
iv.image = UIImage(named: self.testImagesName[i])
iv.tag = i
self.images.addObject(iv)
self.scrollView.addSubview(iv)
}
maxDisplayViewNum = self.images.count
leftViewIndex = 0
rightViewIndex = maxDisplayViewNum - 1
self.updateScrollViewSetting()
}
/**
* updateScrollViewSetting
* スクロールバーに関する初期化処理
*/
func updateScrollViewSetting() {
// スクロールバーのサイズを設定
var contentSize = CGSizeMake(0, imageHeight)
contentSize.width = imageWidth * CGFloat(self.images.count * maxScrollableImages)
// スクロールバーの中央から画像を表示するよう調整
var contentOffSet = CGPointZero
contentOffSet.x = CGFloat(maxScrollableImages) * imageWidth
// 画面の最も左に表示されている画像のインデックス
leftImageIndex = 0
// 画像の初期位置の設定
for (var i = 0; i < self.images.count; i++){
var iv = self.images[i] as UIImageView
iv.frame = CGRectMake(imageWidth * CGFloat(i), 0, imageWidth, imageHeight)
self.images[i] = iv
}
// UIScrollViewの可視領域の左端
leftImageIndex = 0
// ScrollViewへの初期設定
self.scrollView.contentOffset = contentOffSet
self.scrollView.contentSize = contentSize
self.scrollView.showsHorizontalScrollIndicator = false
}
/**
* scrollViewDidScroll
* スクロールが起きる際に呼び出されるイベント
*
* param: scrollView スクロールビュー
*/
func scrollViewDidScroll(scrollView:UIScrollView) {
var currentIndex :NSInteger = NSInteger(scrollView.contentOffset.x / imageWidth)
var indexMovement:NSInteger = currentIndex - leftImageIndex
for (var i = 0; i < abs(indexMovement); i++) {
if (indexMovement > 0){
self.scrollWithDirection(ScrollDirection.kScrollDirectionRight)
}
else {
self.scrollWithDirection(ScrollDirection.kScrollDirectionLeft)
}
}
}
/**
* addImageIndex
* リングバッファの添字を計算する
*
* param: index 画面から溢れ出ている画像の番号(左端と右端)
* param: incremental スクロールした行番号
* returns: リングバッファの添字
*/
func addImageIndex(index:NSInteger, incremental:NSInteger) -> NSInteger {
return (index + incremental + maxDisplayViewNum) % maxDisplayViewNum
}
/**
* scrollWithDirection
* 画像の位置を更新する
*
* param: scrollDirection 左に移動したのか、右に移動したのかを示すステータス変数
*/
func scrollWithDirection(scrollDirection:ScrollDirection) {
var direction :NSInteger = 0
var viewIndex :NSInteger = 0
if (scrollDirection == ScrollDirection.kScrollDirectionLeft){
direction = -1
viewIndex = rightViewIndex
}
else if (scrollDirection == ScrollDirection.kScrollDirectionRight){
direction = 1
viewIndex = leftViewIndex
}
var iv = self.images[viewIndex] as UIImageView
iv.frame.origin.x += imageWidth * CGFloat(self.images.count * direction)
// 画面に映る最も左のインデックスを更新
leftImageIndex += direction
// 画面外の両端の画像のインデックスを更新
leftViewIndex = self.addImageIndex(leftViewIndex , incremental: direction)
rightViewIndex = self.addImageIndex(rightViewIndex, incremental: direction)
}
/**
* didReciveMemoryWarning
* メモリが圧迫されると警告を示す
*/
override func didReceiveMemoryWarning() {
// Dispose of any resources that can be recreated.
super.didReceiveMemoryWarning()
}
}
@seka
Copy link
Author

seka commented Oct 24, 2014

参考:Cocoaの日々: 画像を横に並べたスクロールビューアの作成 [1] アイディア http://cocoadays.blogspot.jp/2010/08/1.html

@seka
Copy link
Author

seka commented Dec 3, 2014

3つ以上の画像が無いと綺麗に表示できない。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment