Cómo hacer que las restricciones networkingimensionen y reposicionen las teclas del keyboard para el paisaje

Me está costando averiguar cómo get el resultado deseado con limitaciones. Podría hacer esto mediante progtwigción, pero parece que debería haber una mejor manera.

Básicamente tengo un keyboard.

  1. La tecla más a la izquierda (Q) y la tecla más a la derecha (P) deben estar a 3 puntos de los lados izquierdo y derecho.

  2. Las 8 teclas entre las teclas Q y P deben estar igualmente espaciadas entre las teclas Q y P

  3. Las teclas deben extenderse en ancho para llenar todo el ancho del espacio entre las teclas Q y P, manteniendo al mismo time el mismo espacio entre ellas.

Básicamente, el keyboard debe hacer lo que hace el keyboard nativo de Apple cuando gira en el paisaje.

¿Se puede hacer esto con restricciones o debo hacer esto programáticamente sin restricciones?

En layout

Sí. El layout automático puede hacer esto.

Siempre que desee que el layout sea el mismo para las orientaciones horizontal y vertical (estoy bastante seguro de que lo hace), una vez que sus restricciones estén configuradas, todo debería funcionar. Si quieres que cambien, eso es posible, pero no voy a abordar esto porque no parece necesario.

Una clarificación

En tu pregunta, dices:

¿Se puede hacer esto con restricciones o debo hacer esto programáticamente sin restricciones?

No estoy seguro, pero quiero comprobar que entiendes que Auto Layout no es solo un generador de interfaces. También puede utilizar de forma muy natural el layout automático del código mediante la manipulación de NSLayoutConstraint y agregarlos a las vistas. Entonces, probablemente tenga al less tres opciones:

  • Use el layout automático y configure las restricciones en Interface Builder.
  • Utilice el layout automático y configure las restricciones en el código.
  • No utilice el layout automático y mueva sus vistas sobre el layoutSubviews: o algo por el estilo.

Eligiendo IB o Código

Puede configurar todo esto en IB. Cada tecla necesitará dos restricciones horizontales y dos restricciones verticales, por lo que administrará al less 104 restricciones para un keyboard de 26 teclas. Más dígitos Y simbolos Hacer esto a mano será insoportable , y cuando lo haces bien, alguien en tu equipo (incluso tú) decidirá que el espaciado de las teclas solo tiene que ser un píxel más.

Una cuadrícula del keyboard tiene tanta regularidad y tantas restricciones que será mucho más fácil usar un poco de código para establecer las restricciones.

Para ser claro: aún usará el layout automático, pero creará las restricciones con el código en lugar de mantenerlas a mano.

Configurar restricciones en el código

Asumo que quieres que las llaves tengan tamaños iguales. Puede imponer esto, junto con el espaciado igual (especificado) entre ellos y un margen fijo a la izquierda y la derecha a la supervisión con una restricción como esta:

 // Substitute your view names here. UIButton *q, *w, *e, *r, *t, *y, *u, *i, *o, *p; NSDictionary *const metrics = @{@"margin": @(3), @"gap": @(4)}; NSDictionary *const views = NSDictionaryOfVariableBindings(q,w,e,r,t,y,u,i,o,p); NSArray *const constraints = [NSLayoutConstraint constraintsWithVisualFormat: @"H:|-margin-[q]-gap-[w(q)]-gap-[e(q)]-gap-[r(q)]-gap-[t(q)]-gap-[y(q)]-gap-[u(q)]-gap-[i(q)]-gap-[o(q)]-gap-[p(q)]-margin-|" options: NSLayoutFormatDirectionLeadingToTrailing metrics: metrics views: views]; // Add constraints to your container view so that they do something. UIView *const container = [self view]; [container addConstraints: constraints]; 

Pero estaría tentado de build un método de ayuda que tomaría una variedad de vistas y generaría las restricciones de eso. Sería algo así:

 -(NSArray *) constraintsForEqualSizeViews: (NSArray *) keys withSuperviewMargin: (CGFloat) margin andSpace: (CGFloat) space { NSMutableArray *const constraints = [NSMutableArray new]; // Note: the keys must be in a superview by now so that // a constraint can be set against its edge. UIView *const leftKey = [keys firstObject]; [constraints addObject: [NSLayoutConstraint constraintWithItem: leftKey attribute: NSLayoutAttributeLeft relatedBy: NSLayoutRelationEqual toItem: [leftKey superview] attribute: NSLayoutAttributeLeft multiplier: 0 constant: margin]]; UIView *const rightKey = [keys firstObject]; [constraints addObject: [NSLayoutConstraint constraintWithItem: rightKey attribute: NSLayoutAttributeRight relatedBy: NSLayoutRelationEqual toItem: [rightKey superview] attribute: NSLayoutAttributeRight multiplier: 0 constant: margin]]; UIView *const templateKeyForEqualSizes = leftKey; NSDictionary *const metrics = @{@"space": @(space)}; for(NSUInteger i=1; i<[keys count]; ++i) { NSDictionary *const views = @{@"previousKey": keys[i-1], @"thisKey": keys[i], @"templateKey": templateKeyForEqualSizes}; [constraints addObjectsFromArray: [NSLayoutConstraint constraintsWithVisualFormat: @"H:[previousKey]-space-[thisKey(templateKey)]" options: NSLayoutFormatDirectionLeftToRight metrics: metrics views: views]]; } NSArray *const immutableArrayToReturn = [constraints copy]; return immutableArrayToReturn; } 

El lenguaje de layout automático se describe en la documentation de Apple .

UIView Frames

No necesita pensar en configurar los frameworks originales para las vistas de las teclas; esta es otra razón para mantenerse alejado del generador de interfaces para describir las keys. Puedes crear tus vistas de esta forma:

 -(NSArray*) keyRowArray: (NSString*) keyNamesString { const NSUInteger keyCount = [keyNamesString length]; NSMutableArray *const keys = [NSMutableArray arrayWithCapacity: keyCount]; for(NSUInteger i=0; i<keyCount; ++i) { NSString *const keyName = [keyNamesString substringWithRange:NSMakeRange(i, 1)]; // Look! No frame needed! XXYourCustomKeyView *const key = [XXYourCustomKeyView new]; // Do key setup – you probably want to add button actions, and such. [key setName: keyName]; [keys addObject: keyName]; } return [keys copy]; } 

UIView propiedad

No administraría todas estas keys en un UIViewController directamente. Los encapsularía dentro de una class XXYourCustomKeyboardView que puede tomar una descripción de keyboard (algo así como una serie de cadenas de filas del keyboard). Su controller puede crear esto, pasar la configuration, configurarse como delegado y días felices.

Método híbrido IB + Code Approach

También es posible que pueda usar un enfoque híbrido en el que configure algunas keys y restricciones en IB:

  • Las teclas que no son de carácter: pestaña, desplazamiento, etc. Su tamaño personalizado y comportamiento especial.
  • La tecla izquierda y derecha de cada fila.
  • La alternancia que compensa las filas desde una cuadrícula.

A continuación, puede agregar las keys entre aquellos que utilizan el código similar al anterior.

Trabajando desde el método de creación de restricciones que proporcioné anteriormente, puede ser más flexible si lo divide en methods separados en una categoría en NSLayoutConstraint :

 @interface NSLayoutConstraint (Keyboard) // This is what it constraint method currently creates in the for loop. +(NSArray*) constraintsForViews: (NSArray*) views imposingEqualSpace: (CGFloat) space; +(NSArray*) constraintsForViewsImposingEqualWidth: (NSArray*) views; // This will also be useful to align a whole row. +(NSArray*) constraintsForViewsImposingSameTopAndBottom: (NSArray*) views; @end 

Déjame saber en los comentarios si algo de esto no está claro. Agregaré aclaraciones si es necesario.