如何使用分段控件动态更改 collectionView 项目大小(如 instagram)
How to dynamically change a collectionView Item size (like instagram) using segmented control
如何构建类似于 Instagram 的 UICollectionView?
我已经创建了三列一:
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
let width = (view.frame.width/3)-2
myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
layout.sectionInset = UIEdgeInsets(top: 49, left: 1, bottom: 1.5, right: 1)
layout.itemSize = CGSize(width: width, height: width)
layout.minimumInteritemSpacing = 1
layout.minimumLineSpacing = 1
myCollectionView?.dataSource = self
myCollectionView?.delegate = self
myCollectionView?.register(PhotoGalleryCell.self, forCellWithReuseIdentifier: cellid)
myCollectionView?.backgroundColor = .white
self.view.addSubview(myCollectionView!)
myCollectionView!.addSubview(segmentedControl)
segmentedControl.topAnchor.constraint(equalTo: myCollectionView!.topAnchor, constant: 12).isActive = true
segmentedControl.centerXAnchor.constraint(equalTo: myCollectionView!.centerXAnchor).isActive = true
segmentedControl.heightAnchor.constraint(equalToConstant: 25).isActive = true
segmentedControl.widthAnchor.constraint(equalTo: myCollectionView!.widthAnchor, constant: -24).isActive = true
但我希望当 selectedControl 的值变为 1 时,Collection 视图的项目变为 1 列宽度,然后如果该值返回到 0,则 collectionView 返回到 3 列设置。
有办法吗?
您需要根据预期的 UI - 网格或列表 更改 collectionView
的 layout
,当在segments
个 UISegmentedControl
。
首先,创建一个enum LayoutType
喜欢,
enum LayoutType {
case list, grid
}
现在,在您的 ViewController
中,创建一个类型 LayoutType
的 属性 layoutType
,最初设置为 .list
,即
var layoutType = LayoutType.list
接下来,为 segmentedControl's
valueChanged
事件实施 @IBAction
。所以,到目前为止 ViewController
看起来像。
class VC: UIViewController, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
var layoutType = LayoutType.list
@IBAction func onChange(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0 {
layoutType = .list
} else {
layoutType = .grid
}
collectionView.reloadData()
}
}
现在根据需要实施 UICollectionViewDataSource
方法。你一定已经这样做了。
现在要在 layoutType
的基础上更改 layout
,您需要遵守 UICollectionViewDelegateFlowLayout
协议并实现以下方法,
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
switch layoutType {
case .list:
return CGSize(width: collectionView.bounds.width, height: 50)
case .grid:
return CGSize(width: (collectionView.bounds.width - 20) / 3, height: 50)
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
这就是您处理事情的方式。如果您仍然遇到任何问题,请告诉我。
如何构建类似于 Instagram 的 UICollectionView? 我已经创建了三列一:
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
let width = (view.frame.width/3)-2
myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
layout.sectionInset = UIEdgeInsets(top: 49, left: 1, bottom: 1.5, right: 1)
layout.itemSize = CGSize(width: width, height: width)
layout.minimumInteritemSpacing = 1
layout.minimumLineSpacing = 1
myCollectionView?.dataSource = self
myCollectionView?.delegate = self
myCollectionView?.register(PhotoGalleryCell.self, forCellWithReuseIdentifier: cellid)
myCollectionView?.backgroundColor = .white
self.view.addSubview(myCollectionView!)
myCollectionView!.addSubview(segmentedControl)
segmentedControl.topAnchor.constraint(equalTo: myCollectionView!.topAnchor, constant: 12).isActive = true
segmentedControl.centerXAnchor.constraint(equalTo: myCollectionView!.centerXAnchor).isActive = true
segmentedControl.heightAnchor.constraint(equalToConstant: 25).isActive = true
segmentedControl.widthAnchor.constraint(equalTo: myCollectionView!.widthAnchor, constant: -24).isActive = true
但我希望当 selectedControl 的值变为 1 时,Collection 视图的项目变为 1 列宽度,然后如果该值返回到 0,则 collectionView 返回到 3 列设置。 有办法吗?
您需要根据预期的 UI - 网格或列表 更改 collectionView
的 layout
,当在segments
个 UISegmentedControl
。
首先,创建一个enum LayoutType
喜欢,
enum LayoutType {
case list, grid
}
现在,在您的 ViewController
中,创建一个类型 LayoutType
的 属性 layoutType
,最初设置为 .list
,即
var layoutType = LayoutType.list
接下来,为 segmentedControl's
valueChanged
事件实施 @IBAction
。所以,到目前为止 ViewController
看起来像。
class VC: UIViewController, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
var layoutType = LayoutType.list
@IBAction func onChange(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0 {
layoutType = .list
} else {
layoutType = .grid
}
collectionView.reloadData()
}
}
现在根据需要实施 UICollectionViewDataSource
方法。你一定已经这样做了。
现在要在 layoutType
的基础上更改 layout
,您需要遵守 UICollectionViewDelegateFlowLayout
协议并实现以下方法,
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
switch layoutType {
case .list:
return CGSize(width: collectionView.bounds.width, height: 50)
case .grid:
return CGSize(width: (collectionView.bounds.width - 20) / 3, height: 50)
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
这就是您处理事情的方式。如果您仍然遇到任何问题,请告诉我。