componentkit

How to use CKStackLayoutComponent to align two labels horizontally?


I've just started playing with ComponentKit and I'm having some difficulties aligning 2 labels horizontally. I want the first one close to the left margin and the second close to the right.

With auto layout, I can do it with this set of constraints:

H:|-0-[_label1]-[_label2]-0-|

Everything I tried doesn't seem to be working, I always get the same result: both labels left-aligned.

This is the super-simple component:

+ (instancetype)newWithText1:(NSString *)text1 text2:(NSString *)text2
{
  return [super
          newWithComponent:
          [CKStackLayoutComponent
           newWithView:{}
           size:{}
           style:{
             .direction = CKStackLayoutDirectionHorizontal,
             .alignItems = CKStackLayoutAlignItemsCenter
           }
           children:{
             {
               [CKLabelComponent
                newWithLabelAttributes:{
                  .string = text1,
                  .font = [UIFont systemFontOfSize:20],
                  .color = [UIColor blackColor]
                }
                viewAttributes:{
                  {@selector(setBackgroundColor:), [UIColor clearColor]}
                }],
               .alignSelf = CKStackLayoutAlignSelfStretch
             },
             {
               [CKLabelComponent
                newWithLabelAttributes:{
                  .string = text2,
                  .font = [UIFont systemFontOfSize:20],
                  .color = [UIColor redColor],
                  .alignment = NSTextAlignmentRight
                }
                viewAttributes:{
                  {@selector(setBackgroundColor:), [UIColor clearColor]}
                }],
               .alignSelf = CKStackLayoutAlignSelfStretch
             }
           }]];
}

If anyone has any advice that would be greatly appreciated.


Solution

  • Great find—this is a shortcoming in our flexbox implementation (CKStackLayoutComponent). You're looking for the equivalent of justify-content: space-between; but we don't support it yet.

    If you'd like to submit a patch to the stack layout implementation to support this, it'd be much appreciated. Otherwise, I'll try to find someone to add support.

    For now, you can fake it by putting in a spacer with flexGrow = YES:

    + (instancetype)newWithText1:(NSString *)text1 text2:(NSString *)text2
    {
      return [super
              newWithComponent:
              [CKStackLayoutComponent
               newWithView:{}
               size:{}
               style:{
                 .direction = CKStackLayoutDirectionHorizontal,
                 .alignItems = CKStackLayoutAlignItemsCenter
               }
               children:{
                 {
                   [CKLabelComponent
                    newWithLabelAttributes:{
                      .string = text1,
                      .font = [UIFont systemFontOfSize:20],
                      .color = [UIColor blackColor]
                    }
                    viewAttributes:{
                      {@selector(setBackgroundColor:), [UIColor clearColor]}
                    }],
                   .alignSelf = CKStackLayoutAlignSelfStretch
                 },
                 {
                  [CKComponent new],
                  .flexGrow = YES,
                 },
                 {
                   [CKLabelComponent
                    newWithLabelAttributes:{
                      .string = text2,
                      .font = [UIFont systemFontOfSize:20],
                      .color = [UIColor redColor],
                      .alignment = NSTextAlignmentRight
                    }
                    viewAttributes:{
                      {@selector(setBackgroundColor:), [UIColor clearColor]}
                    }],
                   .alignSelf = CKStackLayoutAlignSelfStretch
                 }
               }]];
    }