Apple definió claramente cómo subclasificar UIView
en el documento.
Consulte la lista a continuación, especialmente eche un vistazo a initWithFrame:
y layoutSubviews
. El primero está destinado a configurar el marco de su UIView
mientras que el segundo está destinado a configurar el marco y el diseño de sus subvistas.
También recuerde que initWithFrame:
se llama solo si está creando instancias UIView
programáticamente. Si lo está cargando desde un archivo plumín (o un guión gráfico), initWithCoder:
se utilizará. Y en initWithCoder:
el marco aún no se ha calculado, por lo que no puede modificar el marco que configuró en Interface Builder. Como se sugiere en esta respuesta , puede pensar en llamar initWithFrame:
desde initWithCoder:
para configurar el marco.
Finalmente, si carga su UIView
desde una plumilla (o un guión gráfico), también tiene la awakeFromNib
oportunidad de realizar inicializaciones de marcos y diseños personalizados, ya que cuando awakeFromNib
se llama se garantiza que cada vista en la jerarquía no se haya archivado e inicializado.
Del documento de NSNibAwaking
(ahora reemplazado por el documento de awakeFromNib
):
Los mensajes a otros objetos se pueden enviar de forma segura desde dentro de wakekeFromNib, momento en el cual se garantiza que todos los objetos no están archivados e inicializados (aunque no necesariamente despiertos, por supuesto)
También vale la pena señalar que con la distribución automática no debe establecer explícitamente el marco de su vista. En su lugar, se supone que debe especificar un conjunto de restricciones suficientes, de modo que el motor de diseño calcule automáticamente el marco.
Directamente de la documentación :
Métodos para anular
Inicialización
initWithFrame:
Se recomienda que implemente este método. También puede implementar métodos de inicialización personalizados además de, o en lugar de, este método.
initWithCoder:
Implemente este método si carga su vista desde un archivo plum de Interface Builder y su vista requiere una inicialización personalizada.
layerClass
Implemente este método solo si desea que su vista use una capa de animación principal diferente para su almacén de respaldo. Por ejemplo, si está utilizando OpenGL ES para hacer su dibujo, debería anular este método y devolver la clase CAEAGLLayer.
Dibujo e impresión
drawRect:
Implemente este método si su vista dibuja contenido personalizado. Si su vista no hace ningún dibujo personalizado, evite anular este método.
drawRect:forViewPrintFormatter:
Implemente este método solo si desea dibujar el contenido de su vista de manera diferente durante la impresión.
Restricciones
requiresConstraintBasedLayout
Implemente este método de clase si su clase de vista requiere restricciones para funcionar correctamente.
updateConstraints
Implemente este método si su vista necesita crear restricciones personalizadas entre sus subvistas.
alignmentRectForFrame:
, frameForAlignmentRect:
Poner en práctica estos métodos para anular cómo sus puntos de vista están alineados con otros puntos de vista.
Diseño
sizeThatFits:
Implemente este método si desea que su vista tenga un tamaño predeterminado diferente al que normalmente tendría durante las operaciones de cambio de tamaño. Por ejemplo, puede usar este método para evitar que su vista se reduzca hasta el punto en que las subvistas no se puedan mostrar correctamente.
layoutSubviews
Implemente este método si necesita un control más preciso sobre el diseño de sus subvistas que la restricción o los comportamientos de autorizar.
didAddSubview:
, willRemoveSubview:
Poner en práctica estos métodos según sea necesario para realizar un seguimiento de las adiciones y eliminaciones de subvistas.
willMoveToSuperview:
, didMoveToSuperview
Implemente estos métodos según sea necesario para rastrear el movimiento de la vista actual en su jerarquía de vistas.
willMoveToWindow:
, didMoveToWindow
Poner en práctica estos métodos, según sea necesario para seguir el movimiento de la vista a una ventana diferente.
Manejo de eventos:
touchesBegan:withEvent:
, touchesMoved:withEvent:
, touchesEnded:withEvent:
, touchesCancelled:withEvent:
Poner en práctica estos métodos, si usted necesita para manejar eventos de toque directamente. (Para la entrada basada en gestos, use reconocedores de gestos).
gestureRecognizerShouldBegin:
Implemente este método si su vista maneja eventos táctiles directamente y puede querer evitar que los reconocedores de gestos adjuntos activen acciones adicionales.
Gabriele Petronella
fuente
layoutSubviews
?Esto todavía aparece en Google. A continuación se muestra un ejemplo actualizado para swift.
La
didLoad
función le permite poner todo su código de inicialización personalizado. Como otros han mencionado,didLoad
se llamará cuando una vista se cree mediante programacióninit(frame:)
o cuando el deserializador XIB combine una plantilla XIB en su vista a través deinit(coder:)
fuente
draw
método?Hay un resumen decente en la documentación de Apple , y esto está bien cubierto en el curso gratuito de Stanford disponible en iTunes. Presento mi versión TL; DR aquí:
Si su clase se compone principalmente de subvistas, el lugar correcto para asignarlas es en los
init
métodos. Para las vistas, hay dosinit
métodos diferentes a los que se podría llamar, dependiendo de si su vista se instancia desde el código o desde una plumilla / guión gráfico. Lo que hago es escribir mi propiosetup
método, y luego llamarlo desde los métodosinitWithFrame:
yinitWithCoder:
.Si está haciendo un dibujo personalizado, de hecho desea anular
drawRect:
en su vista. Sin embargo, si su vista personalizada es principalmente un contenedor para subvistas, probablemente no necesite hacer eso.Solo anule
layoutSubViews
si desea hacer algo como agregar o eliminar una subvista dependiendo de si está en orientación vertical u horizontal. De lo contrario, debería poder dejarlo solo.fuente
layoutSubViews
, funcionó.layoutSubviews
está destinado a establecer el marco en vistas secundarias, no en la vista en sí.Por lo general
UIView
, el constructor designado esinitWithFrame:(CGRect)frame
y usted debe establecer el marco allí (o adentroinitWithCoder:
), posiblemente ignorando el valor del marco pasado. También puede proporcionar un constructor diferente y establecer el marco allí.fuente
awakeFromNib