그리드 형식과 목록 형식의 표시 전환
소개
그리드 형식과 목록 형식을 전환하는 화면은 가끔 보이지요.
이번에는 CollectionView를 이용한 샘플을 소개합니다.
완성 이미지

구현 절차
구현해 보겠습니다.
1. 그리드 형식의 레이아웃 만들기
두 열마다 레이아웃합니다.
GridFlowLayout.swiftimport UIKit
class GridFlowLayout: UICollectionViewFlowLayout {
let itemHeight: CGFloat = 160
override var itemSize: CGSize {
set {
self.itemSize = CGSizeMake(itemWidth(), itemHeight)
}
get {
return CGSizeMake(itemWidth(), itemHeight)
}
}
override init() {
super.init()
setupLayout()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupLayout()
}
func setupLayout() {
minimumInteritemSpacing = 1
minimumLineSpacing = 1
scrollDirection = .Vertical
}
func itemWidth() -> CGFloat {
return (CGRectGetWidth(collectionView!.frame)/2)-1
}
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint {
return collectionView!.contentOffset
}
}
2. 목록 형식의 레이아웃 만들기
그리드 형식의 레이아웃과 거의 동일한 코드로 중복되지만,
1열마다 레이아웃합니다.
ListFlowLayout.swiftimport UIKit
class ListFlowLayout: UICollectionViewFlowLayout {
var itemHeight: CGFloat = 160
override var itemSize: CGSize {
set {
self.itemSize = CGSizeMake(itemWidth(), itemHeight)
}
get {
return CGSizeMake(itemWidth(), itemHeight)
}
}
override init() {
super.init()
setupLayout()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupLayout()
}
func setupLayout() {
minimumInteritemSpacing = 0
minimumLineSpacing = 1
scrollDirection = .Vertical
}
func itemWidth() -> CGFloat {
return CGRectGetWidth(collectionView!.frame)
}
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint {
return collectionView!.contentOffset
}
}
3. 사용자 지정 CollectionViewCell 만들기
ImageView만 있는 셀을 만듭니다.
import UIKit
class ImageCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
static var identifier: String {
get {
return String(self)
}
}
}
4. 레이아웃 만들기
SegmentedControl 및 CollectionView를 배치합니다.
또한 SegmentedControl은
그리드 형식과 목록 형식을 전환하는 데 사용합니다.
또한 CollectionView만 사용하고 TableView는 사용하지 않습니다.

5. 세그먼트 컨트롤로 표시 형식 전환
5.1. View 유형 정의
그리드 형식과 목록 형식의 두 패턴을 정의합니다.
ViewController.swiftenum ViewType {
case grid
case list
}
5.2. 세그먼트 컨트롤 이벤트를 받고 레이아웃 전환
CollectionView의 setCollectionViewLayout 메서드를 이용해,
소정의 레이아웃(grid or list)으로 변경합니다.
애니메이션을 붙이면 그것처럼 보입니다.
class ViewController: UIViewController {
@IBOutlet weak var typeSegmentControl: UISegmentedControl!
@IBOutlet weak var collectionView: UICollectionView!
let gridFlowLayout = GridFlowLayout()
let listFlowLayout = ListFlowLayout()
var fileNames = [String]()
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
private func setup() {
//テストデータ
for i in 1...10 {
fileNames.append("\(i)")
}
collectionView.collectionViewLayout = gridFlowLayout
}
//セグメントコントロールで表示形式を切り替えます
@IBAction func onDidTappedType(sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case ViewType.grid.hashValue:
changeView(gridFlowLayout)
break
case ViewType.list.hashValue:
changeView(listFlowLayout)
break
default:
break
}
}
//Viewを切り替えます
private func changeView(flowLayout: UICollectionViewFlowLayout) {
UIView.animateWithDuration(0.2) { [weak self] () -> Void in
self?.collectionView.collectionViewLayout.invalidateLayout()
self?.collectionView.setCollectionViewLayout(flowLayout, animated: true)
}
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return fileNames.count
}
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(ImageCollectionViewCell.identifier,
forIndexPath: indexPath) as! ImageCollectionViewCell
cell.imageView.image = UIImage(named: "\(fileNames[indexPath.row])"+".jpg")
return cell
}
}
요약
그리드 형식과 목록 형식을 전환하려면,
TableView와 CollectionView를 함께 사용하는 방법도 있지만,
간단한 레이아웃이라면 CollectionView의 열 수를 조정해도 좋을 것 같습니다.
참고
Reference
이 문제에 관하여(그리드 형식과 목록 형식의 표시 전환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/eKushida/items/7ba0e521e56ac66276d7
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import UIKit
class GridFlowLayout: UICollectionViewFlowLayout {
let itemHeight: CGFloat = 160
override var itemSize: CGSize {
set {
self.itemSize = CGSizeMake(itemWidth(), itemHeight)
}
get {
return CGSizeMake(itemWidth(), itemHeight)
}
}
override init() {
super.init()
setupLayout()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupLayout()
}
func setupLayout() {
minimumInteritemSpacing = 1
minimumLineSpacing = 1
scrollDirection = .Vertical
}
func itemWidth() -> CGFloat {
return (CGRectGetWidth(collectionView!.frame)/2)-1
}
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint {
return collectionView!.contentOffset
}
}
import UIKit
class ListFlowLayout: UICollectionViewFlowLayout {
var itemHeight: CGFloat = 160
override var itemSize: CGSize {
set {
self.itemSize = CGSizeMake(itemWidth(), itemHeight)
}
get {
return CGSizeMake(itemWidth(), itemHeight)
}
}
override init() {
super.init()
setupLayout()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupLayout()
}
func setupLayout() {
minimumInteritemSpacing = 0
minimumLineSpacing = 1
scrollDirection = .Vertical
}
func itemWidth() -> CGFloat {
return CGRectGetWidth(collectionView!.frame)
}
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint {
return collectionView!.contentOffset
}
}
import UIKit
class ImageCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
static var identifier: String {
get {
return String(self)
}
}
}
enum ViewType {
case grid
case list
}
class ViewController: UIViewController {
@IBOutlet weak var typeSegmentControl: UISegmentedControl!
@IBOutlet weak var collectionView: UICollectionView!
let gridFlowLayout = GridFlowLayout()
let listFlowLayout = ListFlowLayout()
var fileNames = [String]()
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
private func setup() {
//テストデータ
for i in 1...10 {
fileNames.append("\(i)")
}
collectionView.collectionViewLayout = gridFlowLayout
}
//セグメントコントロールで表示形式を切り替えます
@IBAction func onDidTappedType(sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case ViewType.grid.hashValue:
changeView(gridFlowLayout)
break
case ViewType.list.hashValue:
changeView(listFlowLayout)
break
default:
break
}
}
//Viewを切り替えます
private func changeView(flowLayout: UICollectionViewFlowLayout) {
UIView.animateWithDuration(0.2) { [weak self] () -> Void in
self?.collectionView.collectionViewLayout.invalidateLayout()
self?.collectionView.setCollectionViewLayout(flowLayout, animated: true)
}
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return fileNames.count
}
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(ImageCollectionViewCell.identifier,
forIndexPath: indexPath) as! ImageCollectionViewCell
cell.imageView.image = UIImage(named: "\(fileNames[indexPath.row])"+".jpg")
return cell
}
}
그리드 형식과 목록 형식을 전환하려면,
TableView와 CollectionView를 함께 사용하는 방법도 있지만,
간단한 레이아웃이라면 CollectionView의 열 수를 조정해도 좋을 것 같습니다.
참고
Reference
이 문제에 관하여(그리드 형식과 목록 형식의 표시 전환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/eKushida/items/7ba0e521e56ac66276d7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)