El problema

He creado un UICollectionViewController con una costumbre UICollectionViewCell.
La costumbre de la célula contiene un grande y rectangular UIView (nombre colorView) y un UILabel (nombre nameLabel).

Cuando la colección se pobló con sus células y puedo imprimir colorView.marco, el impreso de marcos tienen valores incorrectos. Sé que es incorrecto, porque el colorView marcos son más grandes que las células de marco a sí mismos, aunque el colorView se dibuja correctamente.

Sin embargo, si me desplazo a la collectionView suficiente para desencadenar la reutilización de una célula, la colorView.marco ahora tiene valores correctos!
Tengo la necesidad de corregir cuadros porque quiero aplicar las esquinas redondeadas para la colorView capa y tengo la necesidad de corregir coloView tamaño para hacer esto.
Por cierto, en caso de que usted se está preguntando, colorView.los límites también tiene el mismo tamaño incorrecto de valor como la colorView.marco.

La pregunta

¿Por qué son los marcos incorrecta a la hora de crear las células?

Y ahora un poco de código

Este es mi UICollectionViewCell:

class BugCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var colorView: UIView!
    @IBOutlet weak var nameLabel: UILabel!
}

y este es el UICollectionViewController:

import UIKit

let reuseIdentifier = "Cell"
let colors = [UIColor.redColor(), UIColor.blueColor(),
              UIColor.greenColor(), UIColor.purpleColor()]
let labels = ["red", "blue", "green", "purple"]

class BugCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return colors.count
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as BugCollectionViewCell

        println("ColorView frame: \(cell.colorView.frame) Cell frame: \(cell.frame)")

        cell.colorView.backgroundColor = colors[indexPath.row]
        cell.nameLabel.text = labels[indexPath.row]

        return cell
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        let width = self.collectionView?.frame.width
        let height = self.collectionView?.frame.height
        return CGSizeMake(width!, height!/2)
    }
}

La vista de colección es el programa de instalación con el fin de mostrar dos células en un momento, de forma vertical, cada celda contiene un gran rectángulo pintado con un color y una etiqueta con el nombre del color.

Cuando acabo de ejecutar el código anterior en el simulador, me sale el siguiente resultado impreso:

ColorView frame: (0.0,0.0,320.0,568.0) Cell frame: (0.0,0.0,375.0,333.5)
ColorView frame: (0.0,0.0,320.0,568.0) Cell frame: (0.0,343.5,375.0,333.5)

Es un extraño resultado – colorView.marco tiene una altura de 568 puntos, mientras que el marco de la célula es sólo 333.5 puntos de altura.

Si me arrastre el collectionView abajo y una célula se reutiliza, el siguiente resultado es impreso:

ColorView frame: (8.0,8.0,359.0,294.0) Cell frame: (0.0,1030.5,375.0,333.5)
ColorView frame: (8.0,8.0,359.0,294.0) Cell frame: (0.0,343.5,375.0,333.5)

Algo, que no puedo entender, que sucedió a lo largo de la manera que corrige el marco de colorView.

Creo que tiene algo que ver con el hecho de que las células se cargan de la Punta, así que en lugar de utilizar el init(marco: marco) inicializador el controlador utiliza el init(coder: aCoder) inicializador, así que tan pronto como la célula se crea que probablemente viene con algún defecto marco que no puedo editar todos modos.

Yo te agradezco cualquier ayuda que me permite entender lo que está sucediendo!

Estoy usando Xcode 6.1.1. con el SDK de iOS 8.1.

  • Cómo hacer que la posición de ColorView? Usted no está utilizando el diseño automático de la derecha? Creo que lo que está sucediendo es el punto de vista de diseño se carga desde la punta y traducido para el diseño automático. Pero su guión viewcontroller es diferente tamaño para el simulador. Utilizar el diseño automático a la posición de sus puntos de vista y deben funcionar las cosas en ese momento.
  • Hey @CharlieWu, de hecho estoy usando diseño automático… colorView y nameLabel son completamente restringido…
InformationsquelleAutor Felipe Ferri | 2015-02-02

4 Comentarios

  1. 56

    Usted puede conseguir el final de los marcos de su celda, reemplazando layoutIfNeeded() en la Celda personalizada clase como esta:

    override func layoutIfNeeded() {
        super.layoutIfNeeded()
        self.subView.layer.cornerRadius = self.subView.bounds.width / 2
    }

    a continuación, en su UICollectionView Origen de datos método cellForRowAtIndexPath: haga esto:

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! CustomCollectionViewCell
    cell.setNeedsLayout()
    cell.layoutIfNeeded()
    • El primer ejemplo de código aquí está por fin la verdadera respuesta. Gracias.
    • Yo tenía el mismo problema de nuevo y su respuesta fue mejor que la mía. 🙂
    • La misma solución para UITableViewCell así.
    • layoutSubviews() no me ayudan. Sólo les ayudó. Consulte este artículo demasiado medium.com/@abhimuralidharan/….
  2. 16

    Tuve el mismo problema con un UICollectionViewCell el uso de auto restricciones de diseño.

    Tuve que llamar layoutIfNeeded antes de que yo estaba configurando mi subvista que se basó en las opiniones ancho del marco.

    • Donde es exactamente lo que usted llame a layoutIfNeeded? Recuerdo que traté de llamarlo, en el controlador de vista de init pero no funcionó, parecía como si las células se cargan antes de que el auto de diseño fue ejecutado, incluso después de la cola con layoutIfNeeded…
    • Nota al margen: - (void)awakeFromNib { [super awakeFromNib]; [self layoutIfNeeded]; /* frames already calculated here */ }
    • Genial! Gracias.
  3. 8

    Ok, ahora entiendo que la célula se crea antes de diseño automático define sus marcos. Esa es la razón por la que en el momento de la creación de los límites que están mal. Cuando las células se vuelven a utilizar los marcos han sido ya corregida.

    Yo estaba teniendo este problema, mientras que la creación de una costumbre UIView que coloca algunas capas y subvistas en las coordenadas específicas. Cuando las instancias de este UIView fueron creados, la colocación de las subvistas estaban mal (porque el diseño automático no había kick off aún).

    Me enteré de que en lugar de la configuración de la vista de subvistas en init(coder: aCoder) tuve que reemplazar el método layoutSubviews(). Esto es llamado cuando el auto layout pide a cada vista para el diseño de su propio subvistas, así que al menos en este momento la vista principal tiene el marco correcto y lo puedo usar para la colocación de las subvistas correctamente.

    Probablemente si hubiese usado limitaciones en la vista personalizada de código en lugar de tratar a mí mismo con tamaños de fotograma de posicionamiento y, a continuación, el diseño ha sido realizado correctamente y no sería necesario reemplazar layoutSubviews().

    • La mejor solución hasta el momento! Muchas gracias 🙂
    • El mejor lugar para agregar las lógicas para mi personalizar la vista.
  4. 8

    Tenido este problema con Núcleo de Gráficos de dibujo en iOS 10, Swift 3.0.1.

    Agregar este método a UICollectionView subclase:

    override func didMoveToSuperview() {
        super.didMoveToSuperview()
        setNeedsLayout()
        layoutIfNeeded()
    }

    Mi problema era que el Núcleo de Gráficos de formas que no se han calculado correctamente, ya que un layoutSubviews() no lo llamaban.

    • ¿A donde agregar este código?
    • en UICollectionViewCell subclase.
    • Esta fue la única cosa que ayudó en mi caso, gracias!

Dejar respuesta

Please enter your comment!
Please enter your name here