ios - 如何根据屏幕宽度动态设置具有不同字符串长度的多个按钮?
问题描述
我想实现像上面这样的布局(当屏幕的宽度不足以容纳按钮的宽度时自动换行)。但我想不出任何关于如何制作像布局这样的图像的想法。我只能静态实现,而不是动态实现。
在Android中,有一个布局可以实现上述。但我不知道什么可以帮助我快速实现上面的图像。请帮我。
遵循@Matthew Mitchell 的建议。我像下面这样实现它。
我的 ViewController.swift
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var hobbyArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
// self.collectionView!.register(CollectionViewCell.self, forCellWithReuseIdentifier: "cell")
hobbyArray.append("test1")
hobbyArray.append("test2")
hobbyArray.append("test3")
hobbyArray.append("test4")
hobbyArray.append("test5")
hobbyArray.append("test5")
hobbyArray.append("test5123123")
collectionView.reloadData()
}
}
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return hobbyArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.title.text = self.hobbyArray[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let text = self.hobbyArray[indexPath.row]
let cellWidth = text.size(withAttributes:[.font: UIFont.systemFont(ofSize:17)]).width + 25
return CGSize(width: cellWidth, height: 35.0)
}
}
其他代码的实现与@Matthew Mitchell 的代码完全相同。但是,我仍然无法得到我想要实现的东西。
我没能做出我想要的。
解决方案
要有效地做到这一点,您需要一个UICollectionView
带有自定义的FlowLayout
. 我要做一个storyboard
例子。这很复杂,所以我会尽力而为。所有代码都将在步骤下方。
第 1 步:创建一个名为 CollectionViewFlowLayout 的 swift 文件,并在新创建的类中使用 UICollectionViewLayout 代码。
第 2 步:添加UICollectionView
到您的ViewController
第 3 步:将新的 UICollectionView 布局与 CollectionViewFlowLayout 类链接
第 4 步:在 UICollectionView 中创建一个 UICollectionViewCell,为该单元格添加一个标签,并将其限制在单元格的左侧和右侧,并将其垂直居中。在单元格的属性检查器中给它一个可重用的标识符(本例中的“单元格”)
第 6 步:创建一个名为 collectionViewCell 的快速文件,并使用链接到您的 collectionViewCell 的 UICollectionViewCell 类(与第 3 步中链接流程布局的方式相同)。
第 7 步:将 ViewController 代码添加到您的 ViewController 类。此代码允许您将单元格添加到集合视图中。sizeForItemAt 函数将允许您根据放置在每个单元格内的字符串的宽度调整单元格的大小。
代码:
视图控制器:
import UIKit
class viewController: UIViewController {
//Outlets
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
collectionView.delegate = self
collectionView.dataSource = self
}
}
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return YOUR_ITEM_COUNT
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
self.title.text = YOUR_ITEMS_LIST[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let text = YOUR_ITEMS_LIST[indexPath.row]
let cellWidth = text!.size(withAttributes:[.font: UIFont.systemFont(ofSize:17)]).width + 25
return CGSize(width: cellWidth, height: 35.0)
}
}
UICollectionViewCell:
class CollectionViewCell: UICollectionViewCell {
//Outlets
@IBOutlet weak var title: UILabel!
}
UICollectionViewFlowLayout:
import UIKit
class CollectionViewFlowLayout: UICollectionViewFlowLayout {
var tempCellAttributesArray = [UICollectionViewLayoutAttributes]()
let leftEdgeInset: CGFloat = 0
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let cellAttributesArray = super.layoutAttributesForElements(in: rect)
//Oth position cellAttr is InConvience Emoji Cell, from 1st onwards info cells are there, thats why we start count from 2nd position.
if(cellAttributesArray != nil && cellAttributesArray!.count > 1) {
for i in 1..<(cellAttributesArray!.count) {
let prevLayoutAttributes: UICollectionViewLayoutAttributes = cellAttributesArray![i - 1]
let currentLayoutAttributes: UICollectionViewLayoutAttributes = cellAttributesArray![i]
let maximumSpacing: CGFloat = 8
let prevCellMaxX: CGFloat = prevLayoutAttributes.frame.maxX
//UIEdgeInset 30 from left
let collectionViewSectionWidth = self.collectionViewContentSize.width - leftEdgeInset
let currentCellExpectedMaxX = prevCellMaxX + maximumSpacing + (currentLayoutAttributes.frame.size.width )
if currentCellExpectedMaxX < collectionViewSectionWidth {
var frame: CGRect? = currentLayoutAttributes.frame
frame?.origin.x = prevCellMaxX + maximumSpacing
frame?.origin.y = prevLayoutAttributes.frame.origin.y
currentLayoutAttributes.frame = frame ?? CGRect.zero
} else {
// self.shiftCellsToCenter()
currentLayoutAttributes.frame.origin.x = leftEdgeInset
//To Avoid InConvience Emoji Cell
if (prevLayoutAttributes.frame.origin.x != 0) {
currentLayoutAttributes.frame.origin.y = prevLayoutAttributes.frame.origin.y + prevLayoutAttributes.frame.size.height + 08
}
}
}
}
return cellAttributesArray
}
func shiftCellsToCenter() {
if (tempCellAttributesArray.count == 0) {return}
let lastCellLayoutAttributes = self.tempCellAttributesArray[self.tempCellAttributesArray.count-1]
let lastCellMaxX: CGFloat = lastCellLayoutAttributes.frame.maxX
let collectionViewSectionWidth = self.collectionViewContentSize.width - leftEdgeInset
let xAxisDifference = collectionViewSectionWidth - lastCellMaxX
if xAxisDifference > 0 {
for each in self.tempCellAttributesArray{
each.frame.origin.x += xAxisDifference/2
}
}
}
}
推荐阅读
- php - 我的验证器功能有什么问题?
- .net - 如何处理 EndSave 事件(AutoCAD .net vb)?
- javascript - 修改 Web Speech API 的问题?
- android - Google Pixel 中的指纹扫描错误
- ibm-midrange - 如何知道哪些成员嵌入了 SQL
- c - 如何在c中用'%30'替换字符串中的空格
- python - TypeError:ufunc'add'不包含签名匹配类型dtype的循环
- c# - 如何在 Web API 中获取传递给请求的所有参数
- azure-active-directory - 如何使用 terraform 为 AzureAD 应用程序创建 AccessKey
- regex - 从 Apache NiFi 中的 unix 时间戳中删除点的问题