2011-03-19 18 views
5

Quiero ser capaz de diseñar mi propia UITableViewCell en IB. Pero sigo recibiendo una excepción de ref nula cuando intento acceder a la etiqueta que definí en IB.Cómo usar UITableViewCell personalizado desde Interface Builder?

Esto es lo que estoy haciendo:

En Interface Builder:

  • Quité el "Ver" y añadió un UITableViewCell lugar.
  • Se cambió la clase de UITableViewCell a "TestCellView".
  • Agregó un UILabel a la celda.
  • Se agregó una salida "oLblText" al TestCellView y se conectó el UILabel.
  • Se cambió el identificador de la clase a "TestCellView".

Implementar TestCellView.xib.cs

public partial class TestCellView : UITableViewCell 
{ 
    public TestCellView(string sKey) : base(UITableViewCellStyle.Default, sKey) 
    { 
    } 

    public TestCellView(IntPtr oHandle) : base(oHandle) 
    { 
    } 

    public string TestText 
    { 
     get 
     { 
      return this.oLblText.Text; 
     } 
     set 
     { 
         // HERE I get the null ref exception! 
      this.oLblText.Text = value; 
     } 
    } 
} 

** ** Los TestCellView.designer.cs

[MonoTouch.Foundation.Register("TestCellView")] 
public partial class TestCellView { 

    private MonoTouch.UIKit.UILabel __mt_oLblText; 

    #pragma warning disable 0169 
    [MonoTouch.Foundation.Connect("oLblText")] 
    private MonoTouch.UIKit.UILabel oLblText { 
     get { 
      this.__mt_oLblText = ((MonoTouch.UIKit.UILabel)(this.GetNativeField("oLblText"))); 
      return this.__mt_oLblText; 
     } 
     set { 
      this.__mt_oLblText = value; 
      this.SetNativeField("oLblText", value); 
     } 
    } 
} 

En la fuente de mi mesa:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) 
{ 
    TestCellView oCell = (TestCellView)tableView.DequeueReusableCell("myCell"); 
    if(oCell == null) 
    { 
     // I suppose this is wrong but how to do it correctly? 
       // this == my UITableViewSource. 
       NSBundle.MainBundle.LoadNib("TestCellView", this, null); 
     oCell = new TestCellView("myCell"); 
    } 
    oCell.TestText = "Cell " + indexPath.Row; 
    return oCell; 
} 

Tenga en cuenta que NO quiero una solución que implique un UIViewController para cada célula. He visto un par de ejemplos en la web haciendo esto. Solo creo que es una exageración total.

¿Qué estoy haciendo mal?

Respuesta

3

Antes que nada, es una cuestión de diseño. Si su vista de tabla siempre carga una cantidad específica de celdas con contenido estático, como en una vista de "Configuración", cree una celda personalizada para cada fila que desee y conecte cada una con una salida.

Si este no es el caso, entonces usted tiene dos opciones:

  1. crear una clase que hereda el UITableViewCell y cada vista que desee en ella mediante programación, olvidando Interface Builder.
  2. Agregue un nuevo iPhone Vea con el Controlador, reemplace la vista y trátela como lo hizo. Excepto por el hecho de que deberá conectar su celda con una toma de corriente en el propietario del archivo. Entonces, cuando crea una instancia de ese controlador, todas las subvistas de su celda estarán bien.

No es una exageración, o al menos, Apple recomienda que: click and go to the "Loading Custom Table-View Cells From Nib Files" paragraph

PD: Sólo tenía una situación similar y esta es la manera que lo he hecho. En MonoTouch, para este ejemplo, no necesita LoadNib nada. Sólo hacer esto dentro de la anulación GetCell en la fuente de la tabla:

using (CellController controller = new CellController()) 
{ 

    cell = (CustomCell)controller.View; 

} 

Tal vez incluso declaran una salida adicional dentro del objeto CellController para evitar la proyección de UIView.

+2

Así es exactamente como lo tengo ahora. Simplemente no me gusta tener un controlador. La razón es: cuando uso los estilos de celda predeterminados, tampoco tengo un controlador. Entonces, ALLÍ decidió que NO se necesita ningún controlador. Al crear celdas personalizadas, quieren que tengamos un controlador por celda. – Krumelur

+1

Sí, cuando utiliza los estilos de celda predeterminados, no se necesita ningún controlador ya que las celdas se están creando mediante programación. Pero desea utilizar celdas, objetos de interfaz de usuario en general, que se cargan desde un archivo NIB. No basta con soltar una celda personalizada en un archivo NIB. Debe estar conectado de alguna manera con el propietario del archivo que, en este caso, debe ser un UIViewController. –

1

Compruebe esto link. Este es un artículo muy interesante para crear una TableViewCell personalizada. Creo que el error se debe a la carga asincrónica del xib proporcionado por Monotouch.

Usted tiene que proporcionar su propia costructor así:

public TestCellView(string sKey) //: base(UITableViewCellStyle.Default, sKey) 
{ 
    MonoTouch.Foundation.NSBundle.MainBundle.LoadNib ("YOUR NIBNAME", this, null); 
} 

Espero que esto ayude!

+0

De acuerdo con el enlace que proporcionó aquí, el ejemplo de código que ingresó anteriormente no es correcto. El ejemplo en el enlace llama a LoadNib dentro de la implementación ** controller ** y no dentro de la implementación de la célula. –

3

No se puede hacer referencia a ninguna toma de corriente hasta que se carga el Nib. Hay un método que puede anular que le dirá "Su NIB está cargada, ahora puede acceder a los campos". Hasta ese punto, hacer referencia a esos objetos siempre devolverá nulo.

Cuestiones relacionadas