以编程方式创建gridview

时间:2014-12-05 02:44:06

标签: ios swift uiview autolayout nslayoutconstraint

我正在创建一个10x10网格(GridView)视图(CellView)。

我能够为单个尺寸的屏幕创建这个,但到目前为止还无法创建适用于iPhone上所有3个当前屏幕尺寸的解决方案。

gridView是在自动布局中创建的,并且有一些约束:宽度和高度之间的比例相等,并且与水平边缘相距8px。

我有两种方法:

1。)当调用init()来创建CellView时,我将它的框架放在超视图的大小上。

let cellSize = gridView.bounds.width/15 let cellRect = CGRect(origin: CGPoint(x: x, y: y), size: CGSize(width: cellSize, height: cellSize))

这种方法似乎不起作用,并且细胞并不都适合网格。根据除数的变化,它们要么太大要么太小。

2.)我的第二种方法是为细胞使用自动布局。

创建cellView并将其作为子视图添加到gridView后,我添加了2个约束。

var width = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: self.superview, attribute: NSLayoutAttribute.Width, multiplier: 0.0666667, // 1/15 constant: 0) var height = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: self.superview, attribute: NSLayoutAttribute.Height, multiplier: 0.0666667, // 1/15 constant: 0)

不幸的是,这导致cellViews没有出现在屏幕上。检查后,这是由于宽度/高度为0;然而,它们在运行期间的约束中还具有低于0值的额外宽度和高度> 0。

我不确定哪种方法最好。我正在以编程方式创建cellView,并且需要一种适用于所有设备屏幕尺寸的方法。

非常感谢我目前的方法中存在错误的更好的解决方案或想法。

2 个答案:

答案 0 :(得分:1)

您可以在layoutSubviews()中布局视图:

class GridView {
  // number of rows and columns
  private let rows = 10
  private let cols = 10

  // two-dimensional array of your Cell views. You create them elsewhere and add 
  // all of them to GridView
  private let children: [[UIView]]
  // border, here 8 points on each side
  private let insets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
  // spacing between Cell views (not sure if you want this, and you could change it to have
  // different values for horizontal and vertical spacing)
  private let spacing: CGFloat = 1

  override func layoutSubviews() {
    // available size is the total of the widths and heights of your cell views:
    // bounds.width/bounds.height minus edge insets minus spacing between cells
    let availableSize = CGSize(
      width: bounds.width - insets.left - insets.right - CGFloat(cols - 1) * spacing,
      height: bounds.height - insets.top - insets.bottom - CGFloat(rows - 1) * spacing)

    // maximum width and height that will fit
    let maxChildWidth = floor(availableSize.width / CGFloat(cols))
    let maxChildHeight = floor(availableSize.height / CGFloat(rows))

    // childSize should be square
    let childSize = CGSize(
      width: min(maxChildWidth, maxChildHeight),
      height: min(maxChildWidth, maxChildHeight))

    // total area occupied by the cell views, including spacing inbetween
    let totalChildArea = CGSize(
      width: childSize.width * CGFloat(cols) + spacing * CGFloat(cols - 1),
      height: childSize.height * CGFloat(rows) + spacing * CGFloat(rows - 1))

    // center everything in GridView
    let topLeftCorner = CGPoint(
      x: floor((bounds.width - totalChildArea.width) / 2),
      y: floor((bounds.height - totalChildArea.height) / 2))

    for row in 0..<rows {
      for col in 0..<cols {
        let view = children[row][col]
        view.frame = CGRect(
          x: topLeftCorner.x + CGFloat(col) * (childSize.width + spacing),
          y: topLeftCorner.y + CGFloat(row) * (childSize.height + spacing),
          width: childSize.width,
          height: childSize.height)
      }
    }
  }
}

除了GridView太小的一些边缘情况(并且你会得到childSize.widthchildSize.height的负值),这将适用于任何屏幕尺寸。

答案 1 :(得分:0)

也许这是一种扩展知识的练习练习,但如果不是,您可以使用UICollectionView来节省大量时间和麻烦。